Compare commits

...

141 Commits

Author SHA1 Message Date
Tommy Verrall 8d8d436bf0 Update sandbox.env 2024-01-16 12:24:28 +01:00
Jędrzej Stuczyński f4e42d74c4 Merge pull request #4326 from nymtech/bugfix/nymvisor-windows-ci
Bugfix/nymvisor windows ci
2024-01-16 11:36:47 +01:00
Pierre Dommerc 9de1e6e844 chore: remove nym-vpn projects (#4327) 2024-01-16 11:10:26 +01:00
Tommy Verrall 713df39106 Merge pull request #4324 from nymtech/feature/bity-sell
Update text on buy page to Buy/Sell
2024-01-15 16:55:18 +01:00
Jędrzej Stuczyński 5ec4674f9b even more target locking 2024-01-15 15:45:19 +00:00
Jędrzej Stuczyński 58c5092e80 added a dummy main for non unix targets 2024-01-15 15:18:52 +00:00
Jędrzej Stuczyński 677ad54a7f used global unix cfg 2024-01-15 14:54:49 +00:00
fmtabbara 5e17c3199f update text on buy page to buy/sell 2024-01-15 14:32:39 +00:00
Tommy Verrall 3c3a34ec0f Merge pull request #4322 from nymtech/update-localnet-script
Check that localnet is running fromt the scripts dir
2024-01-15 13:43:27 +01:00
Tommy Verrall e9b442e634 Merge pull request #4303 from nymtech/dependabot/npm_and_yarn/follow-redirects-1.15.4
Bump follow-redirects from 1.15.3 to 1.15.4
2024-01-15 13:42:55 +01:00
Tommy Verrall ca02e2bce1 Merge pull request #4310 from nymtech/dependabot/npm_and_yarn/wasm/node-tester/internal-dev/follow-redirects-1.15.4
Bump follow-redirects from 1.15.2 to 1.15.4 in /wasm/node-tester/internal-dev
2024-01-15 13:42:36 +01:00
Tommy Verrall 985ab43fe9 Merge pull request #4306 from nymtech/dependabot/npm_and_yarn/clients/native/examples/js-examples/websocket/follow-redirects-1.15.4
Bump follow-redirects from 1.14.9 to 1.15.4 in /clients/native/examples/js-examples/websocket
2024-01-15 13:42:12 +01:00
dependabot[bot] f4dad37b14 Bump follow-redirects from 1.15.2 to 1.15.4 in /wasm/client/internal-dev (#4311)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-15 11:52:56 +01:00
durch 08a57fa8df Check that we are running fromt the scripts dir 2024-01-15 10:25:51 +01:00
Tommy Verrall 98e88e2f11 Merge pull request #4253 from nymtech/feature/validator-rewarder
Feature/validator rewarder
2024-01-15 09:25:26 +01:00
Tommy Verrall 2a589b049c Merge pull request #4316 from nymtech/feature/bump_vergen
Bump vergen version to latest
2024-01-12 14:44:09 +00:00
Tommy Verrall 9bcd56e254 Merge pull request #4312 from nymtech/dependabot/npm_and_yarn/wasm/mix-fetch/internal-dev/follow-redirects-1.15.4
Bump follow-redirects from 1.15.2 to 1.15.4 in /wasm/mix-fetch/internal-dev
2024-01-12 12:58:55 +00:00
Bogdan-Ștefan Neacşu 025ba2ec5f Bump vergen version to latest 2024-01-12 14:46:37 +02:00
Tommy Verrall 1a1d11c447 Merge pull request #4247 from nymtech/fix/test-route-construction
Only use good nodes for test route construction
2024-01-12 12:28:21 +00:00
serinko 958bc2ae9a [DOCs]: NymVPN alpha - pages for events (#4309)
* initialise new nymvpn guide pages

* docs: nymvpn guide, testing, troubleshooting and faq

* add faq

* remove todo points

* resolve review comments

* change landing page order

* incorporate huxis user feedback

* add binaries link

* change menu naming -> upper case

* final version for cryptotalk demo

* change naming convention client -> cli
2024-01-11 16:34:25 +00:00
Jon Häggblad d3d5cc3424 Don't build wg deps where it's not supported (#4305)
* Don't build wg deps where it's not supported

* Fix compilation

* Another fix

* More fixes

* another fix
2024-01-11 13:53:57 +01:00
Pierre Dommerc a834bb17f8 chore(vpn-desktop): bump version 0.0.2 (#4314)
* bump version

* add nym-vpn html icon
2024-01-11 12:18:33 +01:00
Zane Schepke cee6d8c308 Merge pull request #4298 from nymtech/fix/vpndesktop_ui_divergences
fix(vpn-desktop-ui): fix design divergences
2024-01-11 06:03:54 -05:00
Zane Schepke 142eaf533b fix macos artifact 2024-01-11 06:01:37 -05:00
Jon Häggblad 42365769f8 Update Cargo.lock for nym-vpn-ui (#4313) 2024-01-11 09:52:44 +01:00
pierre 9fc822298f fix overflow padding
fix settings screens
remove spin animation on connect button
use cursor progress
add select-none on some elements
2024-01-11 06:56:01 +01:00
dependabot[bot] cfb9f3d356 Bump follow-redirects in /wasm/mix-fetch/internal-dev
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-10 23:47:45 +00:00
dependabot[bot] ea386b6145 Bump follow-redirects in /wasm/node-tester/internal-dev
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-10 23:47:41 +00:00
pierre 75221cfd3e wip 2024-01-10 18:25:35 +01:00
pierre 50f71a21e0 fix various design divergences 2024-01-10 18:16:55 +01:00
pierre cfa9ecfcc4 fix various design divergences 2024-01-10 17:52:10 +01:00
Jon Häggblad 549b33cd91 Fix clippy in beta toolchain (#4299)
* clippy::lines_filter_map_ok

* clippy::ineffective-open-options
2024-01-10 15:29:05 +01:00
Tommy Verrall be46da9906 Merge pull request #4302 from nymtech/dependabot/npm_and_yarn/nym-api/tests/follow-redirects-1.15.4
Bump follow-redirects from 1.15.1 to 1.15.4 in /nym-api/tests
2024-01-10 13:54:42 +00:00
Tommy Verrall 66d123312f Merge pull request #4301 from nymtech/dependabot/npm_and_yarn/testnet-faucet/follow-redirects-1.15.4
Bump follow-redirects from 1.14.8 to 1.15.4 in /testnet-faucet
2024-01-10 13:54:25 +00:00
Tommy Verrall a29f3db5fb Merge pull request #4304 from nymtech/jon/update-openssl
cargo update -p openssl
2024-01-10 13:53:13 +00:00
dependabot[bot] d0fa1792e2 Bump follow-redirects in /clients/native/examples/js-examples/websocket
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.9 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.9...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-09 19:35:21 +00:00
Jon Häggblad f452d97979 cargo update -p openssl 2024-01-09 14:14:42 +01:00
Jędrzej Stuczyński 9b2d224e54 clippy 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 3f504d7500 fixed builds of other binaries 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 67701290d3 cargo fmt 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 22541f5a79 smoothing some rough edges 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński bd8f666405 config template 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński a3c1541660 actually sending the rewards 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 6c1d14a4bc clippy 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński defd148d73 cli arguments + balance check 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 162ff71814 more granual configs 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 5c864cb055 monitoring done 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński cfc13671a4 most of the issuance monitoring logic 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 668a255e0d issuance score calculation logic 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 31d8352621 persisting rewarding data 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 4f6fe88b4c starting on persistence 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 397ef8723d block signing related code 2024-01-09 11:03:05 +01:00
Jędrzej Stuczyński 2c2223947c wip 2024-01-09 11:03:04 +01:00
Jędrzej Stuczyński e1c0638f1e getting signing rewards 2024-01-09 11:02:41 +01:00
Jędrzej Stuczyński 13fa2119fc wip 2024-01-09 11:02:41 +01:00
Jędrzej Stuczyński 8f24e8f208 starting to integrate scraper into the rewarder 2024-01-09 11:02:40 +01:00
Jędrzej Stuczyński 37dd20ded1 wip2 2024-01-09 11:01:17 +01:00
Jędrzej Stuczyński b4b32bb907 wip 2024-01-09 10:59:52 +01:00
dependabot[bot] c1718154cb Bump follow-redirects from 1.15.3 to 1.15.4
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-09 09:32:28 +00:00
dependabot[bot] 3eb7710a12 Bump follow-redirects from 1.15.1 to 1.15.4 in /nym-api/tests
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.1 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.1...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-09 09:30:41 +00:00
dependabot[bot] d1c9251904 Bump follow-redirects from 1.14.8 to 1.15.4 in /testnet-faucet
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.8 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.8...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-09 09:30:36 +00:00
Tommy Verrall 62894e2b40 Merge pull request #4300 from nymtech/jon/update-lock
Update Cargo.lock files
2024-01-09 09:29:23 +00:00
Jon Häggblad bd7fd1a61c Update Cargo.lock files 2024-01-09 10:12:02 +01:00
pierre 28f118c73b provide lato font 2024-01-08 17:22:25 +01:00
Tommy Verrall 65699736ee Merge pull request #4018 from nymtech/feature/nym-node-api-tests
Initial step to adding nym-node functional tests
2024-01-08 15:49:37 +00:00
benedettadavico caba594c95 update workflow file 2024-01-08 16:23:57 +01:00
benedettadavico 746d52d017 Merge remote-tracking branch 'origin/develop' into feature/nym-node-api-tests 2024-01-08 16:11:38 +01:00
Zane Schepke e323c05b33 Merge pull request #4297 from nymtech/chore/vpndesktop_update_deps
chore(vpn_desktop): update js dependencies
2024-01-08 09:42:34 -05:00
pierre abdf071448 update js dependencies 2024-01-08 15:35:37 +01:00
Zane Schepke a6f2b0e8c8 feat(vpn_desktop): add entry node location selector support (#4296)
* entry selector read from state

* remove entry_node_location from config

---------

Co-authored-by: pierre <dommerc.pierre@gmail.com>
2024-01-08 12:17:53 +01:00
Tommy Verrall f78b4a1742 Merge pull request #4242 from nymtech/feature/basic-scraper
Feature/basic scraper
2024-01-08 11:04:09 +00:00
Tommy Verrall d4fde7b788 Merge pull request #4194 from nymtech/dependabot/cargo/nym-vpn/ui/src-tauri/openssl-0.10.60
Bump openssl from 0.10.59 to 0.10.60 in /nym-vpn/ui/src-tauri
2024-01-08 10:02:19 +00:00
Tommy Verrall d5a2952ef9 Merge pull request #4255 from nymtech/jon/add-cargo-about
Add cargo-about files
2024-01-08 09:59:16 +00:00
Tommy Verrall 206b6ba742 Merge pull request #4274 from nymtech/dependabot/npm_and_yarn/tauri-apps/cli-1.5.6
Bump @tauri-apps/cli from 1.5.2 to 1.5.6
2024-01-08 09:58:13 +00:00
Zane Schepke 67449b1c19 Merge pull request #4295 from nymtech/chore/vpndesktop_bump_version
chore(vpn_desktop): bump version
2024-01-05 12:37:49 -05:00
pierre 8d6e5d4fff bump version 2024-01-05 18:30:19 +01:00
Zane Schepke f448355b35 Merge pull request #4294 from nymtech/feat/vpnapp_overflow_scroll
fix(vpn_desktop): fix vertical overflow
2024-01-05 11:15:52 -05:00
pierre cf78af6b98 redo cursor pointer 2024-01-05 17:01:18 +01:00
pierre d041cfe5c5 disalbe settings not implemented yet 2024-01-05 16:55:33 +01:00
pierre 85b0b6d73d fix vertical overflow 2024-01-05 13:44:01 +01:00
Zane Schepke 685019884f feat(vpn-desktop): support screen UI and routing (#4279)
* add base setting screen and routing

* add version

* add logs icons

* fix comments

* refactor to nested routes

* add settingslayout

* remove useless note

* fix typecheck

* fix exports and optionals

* fix icon

---------

Co-authored-by: pierre <dommerc.pierre@gmail.com>
2024-01-04 15:55:46 +01:00
Tommy Verrall cd9d4eebd3 Merge pull request #4258 from nymtech/jon/exit-policy-for-portless
Apply exit policy check on destination ips without port
2024-01-03 09:55:09 +00:00
Jędrzej Stuczyński 78610c7e28 Chore/nym api commands (#4225)
* created run and init commands for nym-api + nasty mnemonic workaround

* removed dead code

* cargo fmt + clippy

* fixed key loader

* made announce address optional and removed the nonobvious fallback value

* clippy

* removed contract addresses from config template

* fixed conflicting arguments macro

* post-rebasing fixes: applied client macro to balance method
2024-01-03 10:49:10 +01:00
Tommy Verrall 496870b5f6 Merge pull request #4275 from nymtech/dependabot/npm_and_yarn/testnet-faucet/msgpackr-1.10.1
Bump msgpackr from 1.5.5 to 1.10.1 in /testnet-faucet
2024-01-03 08:55:42 +00:00
serinko 7eac5e3529 url correction (#4281) 2024-01-02 14:22:47 +00:00
Jędrzej Stuczyński 4ad4072709 naively resolve gateway credential spending race condition (#4229)
a non-naive solution would require queuing up pending request and batch executing them
2024-01-02 14:47:01 +01:00
serinko bd3711892a remove ccc event pages (#4280) 2024-01-02 13:36:06 +00:00
Jędrzej Stuczyński b5926def85 fixed rebasing artifact 2024-01-02 12:54:12 +00:00
Jędrzej Stuczyński 50cc8bd0bf improved startup sync 2024-01-02 12:54:12 +00:00
Jędrzej Stuczyński fb1b58b5fb fixed startup sync 2024-01-02 12:54:11 +00:00
Jędrzej Stuczyński c3a9ceae52 fixed update_last_processed 2024-01-02 12:54:11 +00:00
Jędrzej Stuczyński c92a7e3e35 Squashed scraper
globally updated sqlx to 0.6.3

wip

basic processing loop

wip

starting on modules

all of the requesting logic, catching up, etc

remaining work includes persisting the data

wip

persisting block data

initial and extremely basic nyxd block scraper
2024-01-02 12:54:11 +00:00
Jędrzej Stuczyński e152c9a99e Merge pull request #4278 from nymtech/bugfix/api-tests
bugfix: gateway average uptime test
2024-01-02 13:29:59 +01:00
Jędrzej Stuczyński 78cce00adf bugfix: gateway average uptime test 2024-01-02 12:11:51 +00:00
Jędrzej Stuczyński 55e00a9a38 Feature/remove feegrant (#4227)
* nym-api using own funds when voting in multisig

* startup check for token balance

* dead code
2024-01-02 13:06:17 +01:00
Jędrzej Stuczyński 6d1b26daeb Merge pull request #4277 from nymtech/chore/1.75.0-lints
Chore/1.75.0 lints
2024-01-02 11:42:50 +01:00
Jędrzej Stuczyński 2d9e34cc81 clippy 2024-01-02 10:27:43 +00:00
Jędrzej Stuczyński 7232fd83d1 ignoring pedantic clippy lints from ephemera 2024-01-02 10:09:03 +00:00
Jędrzej Stuczyński 3816142479 ignoring unused imports created in macro expansions 2024-01-02 10:06:26 +00:00
dependabot[bot] 112ecc2e4c Bump msgpackr from 1.5.5 to 1.10.1 in /testnet-faucet
Bumps [msgpackr](https://github.com/kriszyp/msgpackr) from 1.5.5 to 1.10.1.
- [Release notes](https://github.com/kriszyp/msgpackr/releases)
- [Commits](https://github.com/kriszyp/msgpackr/commits/v1.10.1)

---
updated-dependencies:
- dependency-name: msgpackr
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-28 21:37:47 +00:00
dependabot[bot] 2f0fbd5ebd Bump @tauri-apps/cli from 1.5.2 to 1.5.6
Bumps [@tauri-apps/cli](https://github.com/tauri-apps/tauri) from 1.5.2 to 1.5.6.
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/@tauri-apps/cli-v1.5.2...@tauri-apps/cli-v1.5.6)

---
updated-dependencies:
- dependency-name: "@tauri-apps/cli"
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-28 05:09:29 +00:00
serinko f45a803139 [DOCs]: ccc-event-hotfix (#4273)
* edit script, form warning, faq landing page

* Update nym-vpn.md

update script to include wg changes if need be

* update script tests.sh

* add tests-wireguard.sh script

* syntax edit

* Update nym-vpn.md

updated testing

* remove leftover flag

* edit testing guide

* final copy edits

---------

Co-authored-by: Tommy Verrall <60836166+tommyv1987@users.noreply.github.com>
2023-12-27 08:42:38 +00:00
serinko 7e16932c4a [DOC]: CCC 23 event pages + NymVPN guide (#4261)
* initialise ccc event pages

* compose existing FAQs

* edit flow

* restructure faq

* add vpn install steps

* add testing section

* initialise troubleshooting

* note add warning

* add warning

* add run cli steps

* add args

* document running flow

* add mulwald info to args desc

* add consent warning

* add FAQ questions

* add FAQ questions

* syntax fix

* edit guide flow

* add error troubleshooting point

* add warning to use two gateways

* remove reduntant message

* add clarification on testing

* rename to 37c3 to respect convention

* delete mixnet overview, replace with a link

* delete redundant

* grammar tweaks

* add gui config steps

* syntax fix

* syntax fix

* add releases and simple command info

* syntax edits

* add clarification on test logs

* describe TUN and IP flag

* add embedded video

* spellcheck

---------

Co-authored-by: mfahampshire <mfahampshire@pm.me>
2023-12-22 14:37:28 +00:00
Zane Schepke a0a44509af Merge pull request #4271 from nymtech/feat/vpnapp_ui_zoom
feat(vpn-deskop): add ui zoom level setting
2023-12-22 07:43:35 -05:00
Zane Schepke 852ed78e5d update README 2023-12-21 12:33:58 -05:00
mx 0d52800569 dkg ceremony overview (#4269)
* added initial dkg ceremony info

* rebase with pwnfoo's changes from #4270 

* final tweaks

---------

Co-authored-by: mfahampshire <mfahampshire@pm.me>
2023-12-21 16:55:58 +00:00
Sachin Kamath a1dd9e656d Add info on running full node & general improvements (#4270)
* documentation: add info on nyx full node

* documentation: https info for nym-api
2023-12-21 13:29:03 +00:00
pierre 1ea78e8e97 add ui zoom level setting 2023-12-21 14:25:15 +01:00
Zane Schepke 46d68e5448 Merge pull request #4268 from nymtech/refactor/vpn_desktop_minor
refactor(vpn-desktop): minor changes
2023-12-20 12:09:56 -05:00
pierre 2c820ca0ea update country list, remove app name from topbar 2023-12-20 17:40:53 +01:00
Zane Schepke 2c731cf048 Merge pull request #4265 from nymtech/fix/vpn_desktop_style
refactor(vpn-desktop): minor style changes
2023-12-20 09:37:51 -05:00
pierre 9a1f28bd43 fix spacing issue 2023-12-20 15:27:56 +01:00
Zane Schepke b9493004aa Merge pull request #4264 from nymtech/refactor/vpn_desktop_style
refactor(vpn-desktop): fix style
2023-12-20 08:49:19 -05:00
pierre b27f806c40 fix spacing issue 2023-12-20 14:47:24 +01:00
Pierre Dommerc 08aaa8813e refactor(vpn-desktop): clean ui (#4263)
* set cursor default on disabled state

* fix long error messages overflow

* clean code

* fix hop select component style

* fix exit select button

* add nym vpn icon

* style refactoring

* style refactoring

* fix hover bg country list in light mode

* fix hover bg country list in light mode

---------

Co-authored-by: Zane Schepke <zanecschepke@gmail.com>
2023-12-20 14:13:48 +01:00
Pierre Dommerc dd9f4f24f1 doc(vpn-desktop): update readme (#4260) 2023-12-19 11:33:21 +01:00
Zane Schepke f6c2cab531 feat(vpn-desktop): add exit node location (#4234)
* add entry node selection

* update quick prefix to fastest

* add entry node selection

* update quick prefix to fastest

* add country selection

* add country selection

* remove config properties

* disable entry location for now

* refactor: rename entry location selector command

* remove un-related comment

* refactor: renamed entry location selector

* use translation key for copy

* fix on connect error handling

* use a default entry location for now

* refactor(backend): move country list into module

* refactor(backend): init app state based on restored app data

* fix(backend): connect command

* add comments

* fix country select bug

* add entry_node_location to app config file

* add proper default location handling

* clean code

---------

Co-authored-by: pierre <dommerc.pierre@gmail.com>
2023-12-19 11:15:11 +01:00
Jon Häggblad 10ff165c18 Apply exit policy check on portless packets 2023-12-19 10:33:38 +01:00
Jon Häggblad eec3cc4c47 Add cargo-about files 2023-12-19 09:24:44 +01:00
Jon Häggblad f4dd9a915d Add some license entries to Cargo.toml files (#4250)
* Add Apache 2.0 to bunch of common crates

* Allow some basic licenses

* Add more licenses
2023-12-19 09:21:33 +01:00
Jędrzej Stuczyński dcfd46ecf0 Merge pull request #4257 from nymtech/chore/reduce-verloc-logs
reduced log severity when verloc connection fails
2023-12-18 12:42:40 +00:00
Jędrzej Stuczyński d331e75375 reduced log severity when verloc connection fails 2023-12-18 12:27:25 +00:00
Jędrzej Stuczyński bac0f24cf7 Feature/issued credentials api (#4207)
* split up coconut module a bit

* internal tool for watching dkg state and updating group contract

* debug dkg state

* display past dealer data

* improved EpochState Display impl

* display contract errors + advance epoch state

* check admin

* panic handler

* simplify app.rs

* split action enum

* added new tab with logger information

* new dealing display

* sort by index

* [fixedup] wip: updating epoch issued credentials - OG 92ade10384a6d7b6c6c222d2e29d69d3b3446a4c

* storing and signing partial blinded credentials

* starting cleanup

* fixed coconut tests + clippy

* fixed nym-api tests

* removed dkg-manager tool

it was moved to a different branch

* implemented remaining endpoints

* unit tests + bug fixes

* clippy

* added persistent identity keys to nym-api

theyre not yet announced - this will be in another PR

* cargo fmt

* clippy

* fixed loading of old configs without storage paths set

* added additional logs for blind-sign endpoint

* fixed up licenses

* lowercasing error variants

* changed 'issued_credentials' to a post

* added minimal client support

* fixed the unit test
2023-12-18 12:51:34 +01:00
Tommy Verrall 6bba371c90 Merge pull request #4236 from nymtech/feature/update-sandbox-validator
update sandbox references
2023-12-18 09:55:45 +00:00
Jon Häggblad 404b043591 Add ci-cargo-deny (#4254) 2023-12-16 22:16:29 +01:00
Pierre Dommerc e09b33baff fix(vpn-desktop): typo (#4252) 2023-12-15 14:17:12 +01:00
Pierre Dommerc 82bfab48a5 feat(vpn-desktop): integrate nym-vpn-lib (#4244)
* fix initial selected vpn mode

* wip

* Set gateway config

* Init procedure and reading config

* Update two comments

* add nym-api field to app config

* Remove hardcoded RUST_LOG from package.json

* Use scope instead of explicit drop

* Spawn vpn client in separate thread and separate runtime

* Re-set nym-vpn-lib in Cargo.toml

* add vpn handle to app state

* add vpn client call to disconnect cmd

* wip

* Setup listener tasks

* Read entire env after all

* add env config file to app config

* doc: add notes on config

* refactor env config file as optional

* add logic to connection status changes

* refactor disconnect command

* fix handle click connect button

* update doc

* add some fake delay to establish connection

* localize backend messages

* refactor extract registering listeners into modules

* add more tracing logs

* refactor clean code

* refactor clean code

* refactor vpn config creation

* fix connect app_config read

* refactor rename listener functions

* add backend support for twohop mode

* copy change

* base connected status on Ready message

Ready message sent from vpn client

* filter out specific error

* add logs

* use exported receiver types from nym_vpn_lib

* Handle exit message

* Change to nym-vpn for consistency

* prefix comment with TODO

* update doc

* remove nym_api config property

use the one provided in the env config file

* fix css compile error

* log received backend error (frontend)

---------

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
2023-12-15 13:25:49 +01:00
mx e8956603d7 tweak (#4251) 2023-12-14 15:34:48 +00:00
durch 3126053cbe Add three measurements grace period 2023-12-14 14:50:53 +01:00
Jon Häggblad a81e7e6c53 Tweak task dropped log verbosity (#4249) 2023-12-14 10:26:09 +01:00
Jon Häggblad 723e30fb1d Replace panic with error for inserting duplicate pending ack (#4248) 2023-12-14 10:13:59 +01:00
durch 54266fd5df Only use good nodes for test route construction 2023-12-13 16:39:21 +01:00
mx 951f8e7a74 Max/hide nymvisor intros cleanup (#4246)
* * removed shipyard info for moment
* removed nymvisor page until next release

* removed 'new' from operator and tssdk docs

* removed nymvisor for moment
2023-12-13 12:07:37 +00:00
Tommy Verrall 9ea2eafb2c Update documentation/operators/src/nodes/validator-setup.md
Co-authored-by: Sachin Kamath <github@skamath.me>
2023-12-08 15:25:26 +01:00
Tommy Verrall 061aa6b7bd update sandbox references 2023-12-08 15:10:26 +01:00
dependabot[bot] 7407872b71 Bump openssl from 0.10.59 to 0.10.60 in /nym-vpn/ui/src-tauri
Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.59 to 0.10.60.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.59...openssl-v0.10.60)

---
updated-dependencies:
- dependency-name: openssl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-28 21:56:44 +00:00
benedettadavico 8d9387d3ac Merge remote-tracking branch 'origin/develop' into feature/nym-node-api-tests 2023-11-09 11:22:22 +01:00
benedettadavico e8bc2c7a01 Merge remote-tracking branch 'origin/develop' into feature/nym-node-api-tests 2023-11-06 16:46:31 +01:00
benedettadavico 0486cd2e63 refactoring the utils 2023-10-24 11:16:06 +02:00
benedettadavico 604098844a node-api test updates 2023-10-23 10:59:03 +02:00
benedettadavico 65e35bd2b0 Initial step to adding nym-node functional tests 2023-10-19 12:52:46 +02:00
780 changed files with 15161 additions and 19670 deletions
+21
View File
@@ -0,0 +1,21 @@
name: ci-cargo-deny
on: [workflow_dispatch]
jobs:
cargo-deny:
runs-on: ubuntu-22.04
strategy:
matrix:
checks:
# - advisories
- licenses
- bans sources
continue-on-error: ${{ matrix.checks == 'licenses' }}
steps:
- uses: actions/checkout@v3
- uses: EmbarkStudios/cargo-deny-action@v1
with:
log-level: warn
command: check ${{ matrix.checks }}
argument: --all-features
+3
View File
@@ -17,6 +17,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: install yarn in root
run: cd ../.. yarn install
- name: Install npm
run: npm install
-40
View File
@@ -1,40 +0,0 @@
name: ci-nym-vpn-ui-js
on:
workflow_dispatch:
pull_request:
paths:
- 'nym-vpn/ui/src/**'
- 'nym-vpn/ui/package.json'
- 'nym-vpn/ui/index.html'
jobs:
check:
runs-on: custom-linux
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install Yarn
run: npm install -g yarn
- name: Install dependencies
working-directory: nym-vpn/ui
run: yarn
- name: Type-check
working-directory: nym-vpn/ui
run: yarn typecheck
- name: Check lint
working-directory: nym-vpn/ui
run: yarn lint
- name: Check formatting
working-directory: nym-vpn/ui
run: yarn fmt:check
# - name: Run tests
# working-directory: nym-vpn/ui
# run: yarn test
- name: Check build
working-directory: nym-vpn/ui
run: yarn build
-63
View File
@@ -1,63 +0,0 @@
name: ci-nym-vpn-ui-rust
on:
workflow_dispatch:
pull_request:
paths:
- 'nym-vpn/ui/src-tauri/**'
jobs:
build:
runs-on: custom-linux
env:
CARGO_TERM_COLOR: always
CARGOTOML_PATH: ./nym-vpn/ui/src-tauri/Cargo.toml
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools libayatana-appindicator3-dev
continue-on-error: true
- name: Checkout
uses: actions/checkout@v4
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Prepare build
run: mkdir nym-vpn/ui/dist
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path ${{ env.CARGOTOML_PATH }} --features custom-protocol
# - name: Run all tests
# uses: actions-rs/cargo@v1
# with:
# command: test
# args: --manifest-path ${{ env.CARGOTOML_PATH }}
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path ${{ env.CARGOTOML_PATH }} --all -- --check
- name: Annotate with clippy checks
uses: actions-rs/clippy-check@v1
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --manifest-path ${{ env.CARGOTOML_PATH }} --all-features
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --manifest-path ${{ env.CARGOTOML_PATH }} --all-features --all-targets -- -D warnings
+1
View File
@@ -9,6 +9,7 @@
target
.env
.env.dev
envs/devnet.env
/.vscode/settings.json
validator/.vscode
sample-configs/validator-config.toml
Generated
+270 -295
View File
@@ -661,6 +661,22 @@ dependencies = [
"syn 2.0.38",
]
[[package]]
name = "async-tungstenite"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1e9efbe14612da0a19fb983059a0b621e9cf6225d7018ecab4f9988215540dc"
dependencies = [
"futures-io",
"futures-util",
"log",
"pin-project-lite 0.2.13",
"rustls-native-certs",
"tokio",
"tokio-rustls 0.24.1",
"tungstenite",
]
[[package]]
name = "asynchronous-codec"
version = "0.6.2"
@@ -674,15 +690,6 @@ dependencies = [
"pin-project-lite 0.2.13",
]
[[package]]
name = "atoi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5"
dependencies = [
"num-traits",
]
[[package]]
name = "atoi"
version = "1.0.0"
@@ -987,27 +994,13 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
[[package]]
name = "bls12_381"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54757888b09a69be70b5ec303e382a74227392086ba808cb01eeca29233a2397"
version = "0.8.0"
source = "git+https://github.com/jstuczyn/bls12_381?branch=feature/gt-serialization-0.8.0#c4543fde7d02efea6ecfcf22e14476ddb516b483"
dependencies = [
"digest 0.9.0",
"ff 0.10.1",
"group 0.10.0",
"pairing 0.20.0",
"rand_core 0.6.4",
"subtle 2.4.1",
]
[[package]]
name = "bls12_381"
version = "0.6.0"
source = "git+https://github.com/jstuczyn/bls12_381?branch=gt-serialisation#10fb6f700bfda17c8475af3bfd31e3fec15f2278"
dependencies = [
"digest 0.9.0",
"ff 0.11.1",
"group 0.11.0",
"pairing 0.21.0",
"ff 0.13.0",
"group 0.13.0",
"pairing",
"rand_core 0.6.4",
"subtle 2.4.1",
"zeroize",
@@ -1566,6 +1559,26 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
[[package]]
name = "const_format"
version = "0.2.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673"
dependencies = [
"const_format_proc_macros",
]
[[package]]
name = "const_format_proc_macros"
version = "0.2.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "constant_time_eq"
version = "0.3.0"
@@ -1636,6 +1649,16 @@ dependencies = [
"tendermint-proto",
]
[[package]]
name = "cosmos-sdk-proto"
version = "0.20.0"
source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#41ed4631e146268b0300033c8bbb993d79a49f58"
dependencies = [
"prost 0.12.1",
"prost-types 0.12.1",
"tendermint-proto",
]
[[package]]
name = "cosmrs"
version = "0.15.0"
@@ -1643,7 +1666,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea"
dependencies = [
"bip32",
"cosmos-sdk-proto",
"cosmos-sdk-proto 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ecdsa 0.16.8",
"eyre",
"k256",
"rand_core 0.6.4",
"serde",
"serde_json",
"signature 2.1.0",
"subtle-encoding",
"tendermint",
"thiserror",
]
[[package]]
name = "cosmrs"
version = "0.15.0"
source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features#41ed4631e146268b0300033c8bbb993d79a49f58"
dependencies = [
"bip32",
"cosmos-sdk-proto 0.20.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
"ecdsa 0.16.8",
"eyre",
"k256",
@@ -1761,30 +1803,15 @@ dependencies = [
"toml 0.5.11",
]
[[package]]
name = "crc"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23"
dependencies = [
"crc-catalog 1.1.1",
]
[[package]]
name = "crc"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
dependencies = [
"crc-catalog 2.2.0",
"crc-catalog",
]
[[package]]
name = "crc-catalog"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403"
[[package]]
name = "crc-catalog"
version = "2.2.0"
@@ -2214,6 +2241,16 @@ dependencies = [
"darling_macro 0.14.4",
]
[[package]]
name = "darling"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
dependencies = [
"darling_core 0.20.3",
"darling_macro 0.20.3",
]
[[package]]
name = "darling_core"
version = "0.13.4"
@@ -2242,6 +2279,20 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "darling_core"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.38",
]
[[package]]
name = "darling_macro"
version = "0.13.4"
@@ -2264,6 +2315,17 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "darling_macro"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core 0.20.3",
"quote",
"syn 2.0.38",
]
[[package]]
name = "dashmap"
version = "5.5.3"
@@ -2578,12 +2640,6 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "dotenvy"
version = "0.15.7"
@@ -2779,26 +2835,6 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "enum-iterator"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45a0ac4aeb3a18f92eaf09c6bb9b3ac30ff61ca95514fc58cbead1c9a6bf5401"
dependencies = [
"enum-iterator-derive",
]
[[package]]
name = "enum-iterator-derive"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
]
[[package]]
name = "env_logger"
version = "0.7.1"
@@ -2995,9 +3031,9 @@ dependencies = [
[[package]]
name = "eyre"
version = "0.6.8"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb"
checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799"
dependencies = [
"indenter",
"once_cell",
@@ -3030,26 +3066,6 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]]
name = "ff"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f"
dependencies = [
"rand_core 0.6.4",
"subtle 2.4.1",
]
[[package]]
name = "ff"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924"
dependencies = [
"rand_core 0.6.4",
"subtle 2.4.1",
]
[[package]]
name = "ff"
version = "0.12.1"
@@ -3066,6 +3082,7 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
dependencies = [
"bitvec",
"rand_core 0.6.4",
"subtle 2.4.1",
]
@@ -3519,30 +3536,6 @@ dependencies = [
"web-sys",
]
[[package]]
name = "group"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912"
dependencies = [
"byteorder",
"ff 0.10.1",
"rand_core 0.6.4",
"subtle 2.4.1",
]
[[package]]
name = "group"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89"
dependencies = [
"byteorder",
"ff 0.11.1",
"rand_core 0.6.4",
"subtle 2.4.1",
]
[[package]]
name = "group"
version = "0.12.1"
@@ -4286,6 +4279,15 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.9"
@@ -5912,6 +5914,15 @@ dependencies = [
"libc",
]
[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
dependencies = [
"libc",
]
[[package]]
name = "nym-api"
version = "1.1.34"
@@ -5937,6 +5948,7 @@ dependencies = [
"futures-util",
"getset",
"humantime-serde",
"itertools 0.12.0",
"lazy_static",
"log",
"nym-api-requests",
@@ -5979,7 +5991,7 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"sqlx 0.6.3",
"sqlx",
"tap",
"tempfile",
"thiserror",
@@ -5997,14 +6009,16 @@ name = "nym-api-requests"
version = "0.1.0"
dependencies = [
"bs58 0.4.0",
"cosmrs",
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
"cosmwasm-std",
"getset",
"nym-coconut-interface",
"nym-crypto",
"nym-mixnet-contract-common",
"nym-node-requests",
"schemars",
"serde",
"tendermint",
"ts-rs",
]
@@ -6022,6 +6036,7 @@ dependencies = [
"rand 0.7.3",
"thiserror",
"url",
"zeroize",
]
[[package]]
@@ -6052,7 +6067,7 @@ name = "nym-bity-integration"
version = "0.1.0"
dependencies = [
"anyhow",
"cosmrs",
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
"eyre",
"k256",
"nym-cli-commands",
@@ -6097,7 +6112,7 @@ dependencies = [
"cfg-if",
"clap 4.4.7",
"comfy-table",
"cosmrs",
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
"cosmwasm-std",
"cw-utils",
"handlebars",
@@ -6204,7 +6219,7 @@ dependencies = [
"serde",
"serde_json",
"sha2 0.10.8",
"sqlx 0.6.3",
"sqlx",
"tap",
"tempfile",
"thiserror",
@@ -6257,14 +6272,14 @@ dependencies = [
name = "nym-coconut"
version = "0.5.0"
dependencies = [
"bls12_381 0.6.0",
"bls12_381",
"bs58 0.4.0",
"criterion",
"digest 0.9.0",
"doc-comment",
"ff 0.11.1",
"ff 0.13.0",
"getrandom 0.2.10",
"group 0.11.0",
"group 0.13.0",
"itertools 0.10.5",
"nym-dkg",
"nym-pemstore",
@@ -6274,6 +6289,7 @@ dependencies = [
"serde_derive",
"sha2 0.9.9",
"thiserror",
"zeroize",
]
[[package]]
@@ -6340,7 +6356,7 @@ version = "0.1.0"
dependencies = [
"async-trait",
"log",
"sqlx 0.5.13",
"sqlx",
"thiserror",
"tokio",
]
@@ -6364,8 +6380,8 @@ dependencies = [
name = "nym-credentials"
version = "0.1.0"
dependencies = [
"bls12_381 0.5.0",
"cosmrs",
"bls12_381",
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
"log",
"nym-api-requests",
"nym-coconut-interface",
@@ -6373,6 +6389,7 @@ dependencies = [
"nym-validator-client",
"rand 0.7.3",
"thiserror",
"zeroize",
]
[[package]]
@@ -6406,11 +6423,11 @@ name = "nym-dkg"
version = "0.1.0"
dependencies = [
"bitvec",
"bls12_381 0.6.0",
"bls12_381",
"bs58 0.4.0",
"criterion",
"ff 0.11.1",
"group 0.11.0",
"ff 0.13.0",
"group 0.13.0",
"lazy_static",
"nym-contracts-common",
"nym-pemstore",
@@ -6526,7 +6543,7 @@ dependencies = [
"rand 0.8.5",
"serde",
"serde_json",
"sqlx 0.5.13",
"sqlx",
"subtle-encoding",
"thiserror",
"tokio",
@@ -6723,7 +6740,6 @@ dependencies = [
"nym-types",
"nym-validator-client",
"opentelemetry",
"pretty_env_logger",
"rand 0.7.3",
"serde",
"serde_json",
@@ -6848,7 +6864,7 @@ dependencies = [
"reqwest",
"serde",
"serde_json",
"sqlx 0.6.3",
"sqlx",
"tap",
"tempfile",
"thiserror",
@@ -6869,7 +6885,7 @@ dependencies = [
"pretty_env_logger",
"rocket",
"serde",
"sqlx 0.5.13",
"sqlx",
"thiserror",
"tokio",
]
@@ -7377,7 +7393,7 @@ dependencies = [
"reqwest",
"serde",
"serde_json",
"sqlx 0.5.13",
"sqlx",
"thiserror",
"tokio",
]
@@ -7452,7 +7468,7 @@ name = "nym-types"
version = "1.0.0"
dependencies = [
"base64 0.21.4",
"cosmrs",
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
"cosmwasm-std",
"eyre",
"hmac 0.12.1",
@@ -7486,7 +7502,7 @@ dependencies = [
"bip32",
"bip39",
"colored",
"cosmrs",
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
"cosmwasm-std",
"cw-controllers",
"cw-utils",
@@ -7528,6 +7544,40 @@ dependencies = [
"zeroize",
]
[[package]]
name = "nym-validator-rewarder"
version = "0.1.0"
dependencies = [
"anyhow",
"bip39",
"clap 4.4.7",
"cosmwasm-std",
"futures",
"humantime 2.1.0",
"humantime-serde",
"nym-bin-common",
"nym-coconut",
"nym-coconut-bandwidth-contract-common",
"nym-coconut-dkg-common",
"nym-config",
"nym-credentials",
"nym-crypto",
"nym-network-defaults",
"nym-task",
"nym-validator-client",
"nyxd-scraper",
"serde",
"serde_with",
"sha2 0.10.8",
"sqlx",
"thiserror",
"time",
"tokio",
"tracing",
"url",
"zeroize",
]
[[package]]
name = "nym-vesting-contract-common"
version = "0.7.0"
@@ -7546,7 +7596,7 @@ dependencies = [
name = "nym-wallet-types"
version = "1.0.0"
dependencies = [
"cosmrs",
"cosmrs 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cosmwasm-std",
"hex-literal",
"nym-config",
@@ -7624,6 +7674,28 @@ dependencies = [
"url",
]
[[package]]
name = "nyxd-scraper"
version = "0.1.0"
dependencies = [
"async-trait",
"const_format",
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
"eyre",
"futures",
"nym-bin-common",
"sha2 0.10.8",
"sqlx",
"tendermint",
"tendermint-rpc",
"thiserror",
"tokio",
"tokio-stream",
"tokio-util",
"tracing",
"url",
]
[[package]]
name = "object"
version = "0.32.1"
@@ -7689,9 +7761,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl"
version = "0.10.57"
version = "0.10.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671"
dependencies = [
"bitflags 2.4.1",
"cfg-if",
@@ -7730,9 +7802,9 @@ dependencies = [
[[package]]
name = "openssl-sys"
version = "0.9.93"
version = "0.9.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7"
dependencies = [
"cc",
"libc",
@@ -7882,20 +7954,11 @@ dependencies = [
[[package]]
name = "pairing"
version = "0.20.0"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7de9d09263c9966e8196fe0380c9dbbc7ea114b5cf371ba29004bc1f9c6db7f3"
checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f"
dependencies = [
"group 0.10.0",
]
[[package]]
name = "pairing"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2e415e349a3006dd7d9482cdab1c980a845bed1377777d768cb693a44540b42"
dependencies = [
"group 0.11.0",
"group 0.13.0",
]
[[package]]
@@ -9790,9 +9853,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.107"
version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [
"itoa",
"ryu",
@@ -9841,6 +9904,35 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_with"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23"
dependencies = [
"base64 0.21.4",
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.0.2",
"serde",
"serde_json",
"serde_with_macros",
"time",
]
[[package]]
name = "serde_with_macros"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788"
dependencies = [
"darling 0.20.3",
"proc-macro2",
"quote",
"syn 2.0.38",
]
[[package]]
name = "serde_yaml"
version = "0.9.25"
@@ -10159,17 +10251,6 @@ dependencies = [
"der 0.7.8",
]
[[package]]
name = "sqlformat"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4"
dependencies = [
"itertools 0.10.5",
"nom",
"unicode_categories",
]
[[package]]
name = "sqlformat"
version = "0.2.2"
@@ -10181,70 +10262,14 @@ dependencies = [
"unicode_categories",
]
[[package]]
name = "sqlx"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b"
dependencies = [
"sqlx-core 0.5.13",
"sqlx-macros 0.5.13",
]
[[package]]
name = "sqlx"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188"
dependencies = [
"sqlx-core 0.6.3",
"sqlx-macros 0.6.3",
]
[[package]]
name = "sqlx-core"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5"
dependencies = [
"ahash 0.7.6",
"atoi 0.4.0",
"bitflags 1.3.2",
"byteorder",
"bytes",
"chrono",
"crc 2.1.0",
"crossbeam-queue",
"either",
"event-listener",
"flume",
"futures-channel",
"futures-core",
"futures-executor",
"futures-intrusive",
"futures-util",
"hashlink 0.7.0",
"hex",
"indexmap 1.9.3",
"itoa",
"libc",
"libsqlite3-sys",
"log",
"memchr",
"once_cell",
"paste",
"percent-encoding",
"rustls 0.19.1",
"sha2 0.10.8",
"smallvec",
"sqlformat 0.1.8",
"sqlx-rt 0.5.13",
"stringprep",
"thiserror",
"tokio-stream",
"url",
"webpki 0.21.4",
"webpki-roots 0.21.1",
"sqlx-core",
"sqlx-macros",
]
[[package]]
@@ -10254,12 +10279,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029"
dependencies = [
"ahash 0.7.6",
"atoi 1.0.0",
"atoi",
"bitflags 1.3.2",
"byteorder",
"bytes",
"chrono",
"crc 3.0.1",
"crc",
"crossbeam-queue",
"dotenvy",
"either",
@@ -10285,34 +10310,16 @@ dependencies = [
"rustls-pemfile",
"sha2 0.10.8",
"smallvec",
"sqlformat 0.2.2",
"sqlx-rt 0.6.3",
"sqlformat",
"sqlx-rt",
"stringprep",
"thiserror",
"time",
"tokio-stream",
"url",
"webpki-roots 0.22.6",
]
[[package]]
name = "sqlx-macros"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1"
dependencies = [
"dotenv",
"either",
"heck 0.4.1",
"once_cell",
"proc-macro2",
"quote",
"sha2 0.10.8",
"sqlx-core 0.5.13",
"sqlx-rt 0.5.13",
"syn 1.0.109",
"url",
]
[[package]]
name = "sqlx-macros"
version = "0.6.3"
@@ -10326,23 +10333,12 @@ dependencies = [
"proc-macro2",
"quote",
"sha2 0.10.8",
"sqlx-core 0.6.3",
"sqlx-rt 0.6.3",
"sqlx-core",
"sqlx-rt",
"syn 1.0.109",
"url",
]
[[package]]
name = "sqlx-rt"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae"
dependencies = [
"once_cell",
"tokio",
"tokio-rustls 0.22.0",
]
[[package]]
name = "sqlx-rt"
version = "0.6.3"
@@ -10475,7 +10471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7e94b1ec00bad60e6410e058b52f1c66de3dc5fe4d62d09b3e52bb7d3b73e25"
dependencies = [
"base64 0.13.1",
"crc 3.0.1",
"crc",
"lazy_static",
"md-5",
"rand 0.8.5",
@@ -10709,6 +10705,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfbf0a4753b46a190f367337e0163d0b552a2674a6bac54e74f9f2cdcde2969b"
dependencies = [
"async-trait",
"async-tungstenite",
"bytes",
"flex-error",
"futures",
@@ -10820,6 +10817,8 @@ dependencies = [
"deranged",
"itoa",
"js-sys",
"libc",
"num_threads",
"powerfmt",
"serde",
"time-core",
@@ -10917,17 +10916,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
dependencies = [
"rustls 0.19.1",
"tokio",
"webpki 0.21.4",
]
[[package]]
name = "tokio-rustls"
version = "0.23.4"
@@ -11014,16 +11002,16 @@ dependencies = [
[[package]]
name = "tokio-util"
version = "0.7.9"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d"
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
dependencies = [
"bytes",
"futures-core",
"futures-io",
"futures-sink",
"futures-util",
"hashbrown 0.12.3",
"hashbrown 0.14.1",
"pin-project-lite 0.2.13",
"slab",
"tokio",
@@ -11463,6 +11451,7 @@ dependencies = [
"log",
"native-tls",
"rand 0.8.5",
"rustls 0.21.7",
"sha1",
"thiserror",
"url",
@@ -11780,18 +11769,13 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vergen"
version = "7.4.3"
version = "8.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447f9238a4553957277b3ee09d80babeae0811f1b3baefb093de1c0448437a37"
checksum = "1290fd64cc4e7d3c9b07d7f333ce0ce0007253e32870e632624835cc80b83939"
dependencies = [
"anyhow",
"cfg-if",
"enum-iterator",
"getset",
"git2",
"rustc_version 0.4.0",
"rustversion",
"thiserror",
"time",
]
@@ -12077,15 +12061,6 @@ dependencies = [
"untrusted 0.9.0",
]
[[package]]
name = "webpki-roots"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
dependencies = [
"webpki 0.21.4",
]
[[package]]
name = "webpki-roots"
version = "0.22.6"
@@ -12205,7 +12180,7 @@ checksum = "465a03cc11e9a7d7b4f9f99870558fe37a102b65b93f8045392fef7c67b39e80"
dependencies = [
"arc-swap",
"async-trait",
"crc 3.0.1",
"crc",
"log",
"rand 0.8.5",
"serde",
@@ -12256,7 +12231,7 @@ dependencies = [
"arc-swap",
"async-trait",
"bytes",
"crc 3.0.1",
"crc",
"log",
"rand 0.8.5",
"thiserror",
+19 -2
View File
@@ -67,6 +67,7 @@ members = [
"common/nymsphinx/params",
"common/nymsphinx/routing",
"common/nymsphinx/types",
"common/nyxd-scraper",
"common/pemstore",
"common/socks5-client-core",
"common/socks5/proxy-helpers",
@@ -101,6 +102,7 @@ members = [
"nym-node",
"nym-node/nym-node-requests",
"nym-outfox",
"nym-validator-rewarder",
"tools/internal/ssl-inject",
"tools/internal/sdk-version-bump",
"tools/nym-cli",
@@ -123,6 +125,7 @@ default-members = [
"nym-api",
"tools/nymvisor",
"explorer-api",
"nym-validator-rewarder",
]
exclude = ["explorer", "contracts", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "nym-vpn/ui/src-tauri", "cpu-cycles"]
@@ -159,10 +162,12 @@ reqwest = "0.11.22"
schemars = "0.8.1"
serde = "1.0.152"
serde_json = "1.0.91"
sqlx = "0.6.3"
tap = "1.0.1"
time = "0.3.30"
thiserror = "1.0.48"
tokio = "1.24.1"
tokio = "1.33.0"
tokio-util = "0.7.10"
tokio-tungstenite = "0.20.1"
tracing = "0.1.37"
tungstenite = { version = "0.20.1", default-features = false }
@@ -172,6 +177,14 @@ utoipa-swagger-ui = "3.1.5"
url = "2.4"
zeroize = "1.6.0"
# coconut/DKG related
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch ="feature/gt-serialization-0.8.0" }
group = "0.13.0"
ff = "0.13.0"
# cosmwasm-related
cosmwasm-derive = "=1.3.0"
cosmwasm-schema = "=1.3.0"
@@ -190,7 +203,11 @@ cw-controllers = { version = "=1.1.0" }
# cosmrs-related
bip32 = "0.5.1"
cosmrs = "=0.15.0"
# temporarily using a fork again (yay.) because we need staking and slashing support
cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch ="nym-temp/all-validator-features" }
#cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" } # unfortuntely we need a fork by yours truly to get the staking support
tendermint = "0.34" # same version as used by cosmrs
tendermint-rpc = "0.34" # same version as used by cosmrs
prost = "0.12"
+70
View File
@@ -0,0 +1,70 @@
<html>
<head>
<style>
@media (prefers-color-scheme: dark) {
body {
background: #333;
color: white;
}
a {
color: skyblue;
}
}
.container {
font-family: sans-serif;
max-width: 800px;
margin: 0 auto;
}
.intro {
text-align: center;
}
.licenses-list {
list-style-type: none;
margin: 0;
padding: 0;
}
.license-used-by {
margin-top: -10px;
}
.license-text {
max-height: 200px;
overflow-y: scroll;
white-space: pre-wrap;
}
</style>
</head>
<body>
<main class="container">
<div class="intro">
<h1>Third Party Licenses</h1>
<p>This page lists the licenses of the projects used in cargo-about.</p>
</div>
<h2>Overview of licenses:</h2>
<ul class="licenses-overview">
{{#each overview}}
<li><a href="#{{id}}">{{name}}</a> ({{count}})</li>
{{/each}}
</ul>
<h2>All license text:</h2>
<ul class="licenses-list">
{{#each licenses}}
<li class="license">
<h3 id="{{id}}">{{name}}</h3>
<h4>Used by:</h4>
<ul class="license-used-by">
{{#each used_by}}
<li><a href="{{#if crate.repository}} {{crate.repository}} {{else}} https://crates.io/crates/{{crate.name}} {{/if}}">{{crate.name}} {{crate.version}}</a></li>
{{/each}}
</ul>
<pre class="license-text">{{text}}</pre>
</li>
{{/each}}
</ul>
</main>
</body>
</html>
+19
View File
@@ -0,0 +1,19 @@
private = { ignore = true }
accepted = [
"0BSD",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"CC0-1.0",
"ISC",
"MIT",
"MPL-2.0",
"Unicode-DFS-2016",
"OpenSSL",
]
workarounds = [
"ring",
"rustls",
]
+1
View File
@@ -5,6 +5,7 @@ authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej St
description = "Implementation of the Nym Client"
edition = "2021"
rust-version = "1.65"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -1667,9 +1667,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"dev": true,
"funding": [
{
@@ -5800,9 +5800,9 @@
}
},
"follow-redirects": {
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"dev": true
},
"forwarded": {
@@ -3,6 +3,7 @@ name = "nym-client-websocket-requests"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+1
View File
@@ -5,6 +5,7 @@ authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021"
rust-version = "1.56"
license.workspace = true
[dependencies]
clap = { workspace = true, features = ["cargo", "derive"] }
@@ -15,4 +15,4 @@ prod:
mixnode_identity: 3pMCJswCyA19MGYWGDWT5fBk2M8ybSZGXttyAoNY5gBB
gateway_identity: 2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh
log_level: error
time_zone: utc
time_zone: utc
@@ -1,4 +1,6 @@
import { dir } from "console";
import { readFileSync } from "fs";
import { dirname } from "path";
import { TLogLevelName } from "tslog";
import YAML from "yaml";
@@ -10,9 +12,11 @@ class ConfigHandler {
public commonConfig: { request_headers: object };
private currentEnvironment: string;
public environment: string;
public environmnetConfig: {
public environmentConfig: {
log_level: TLogLevelName;
time_zone: string;
api_base_url: string;
@@ -35,8 +39,9 @@ class ConfigHandler {
private setCommonConfig(): void {
try {
const baseWorkingDirectory = __dirname;
this.commonConfig = YAML.parse(
readFileSync("src/config/config.yaml", "utf8")
readFileSync(baseWorkingDirectory + "/config.yaml", "utf8"),
).common;
} catch (error) {
throw Error(`Error reading common config: (${error})`);
@@ -46,14 +51,24 @@ class ConfigHandler {
private setEnvironmentConfig(environment: string): void {
this.ensureEnvironmentIsValid(environment);
try {
this.environmnetConfig = YAML.parse(
readFileSync("src/config/config.yaml", "utf8")
const baseWorkingDirectory = __dirname;
this.environmentConfig = YAML.parse(
readFileSync(baseWorkingDirectory + "/config.yaml", "utf8"),
)[environment];
} catch (error) {
console.log("fadsfasdfasdfsdfsa")
throw Error(`Error reading environment config: (${error})`);
}
}
public getEnvironmentConfig(environment: string): any {
const baseWorkingDirectory = __dirname;
return (
this.environmentConfig ||
YAML.parse(readFileSync(baseWorkingDirectory + "/config.yaml", "utf8"))[environment]
);
}
private ensureEnvironmentIsValid(environment: string): void {
if (this.validEnvironments.indexOf(environment) === -1) {
throw Error(`Config environment is not valid: "${environment}"`);
+4
View File
@@ -0,0 +1,4 @@
module.exports = {
ConfigHandler: require('./config/configHandler.ts'),
RestClient: require('./restClient/RestClient.ts')
};
@@ -13,9 +13,9 @@ import ConfigHandler from "../config/configHandler";
const config = ConfigHandler.getInstance();
const log = new Logger({
minLevel: config.environmnetConfig.log_level,
minLevel: config.environmentConfig.log_level,
dateTimeTimezone:
config.environmnetConfig.time_zone ||
config.environmentConfig.time_zone ||
Intl.DateTimeFormat().resolvedOptions().timeZone,
});
@@ -24,7 +24,7 @@ function isSet(property): boolean {
}
export class RestClient {
private static authToken: string;
public static authToken: string;
private axiosInstance: AxiosInstance;
@@ -83,7 +83,7 @@ export class RestClient {
data,
additionalConfigs,
params,
})
}),
);
await this.axiosInstance
@@ -214,7 +214,7 @@ export class RestClient {
if (isSet(additionalConfigs)) {
logRecord = `${logRecord}\nAdditional Configuration: ${stringify(
additionalConfigs
additionalConfigs,
)}`;
}
+1
View File
@@ -2,6 +2,7 @@
name = "async-file-watcher"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+2
View File
@@ -2,6 +2,7 @@
name = "nym-bandwidth-controller"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -10,6 +11,7 @@ bip39 = { workspace = true }
rand = "0.7.3"
thiserror = { workspace = true }
url = { workspace = true }
zeroize = { workspace = true }
nym-coconut-interface = { path = "../coconut-interface" }
nym-credential-storage = { path = "../credential-storage" }
+12 -15
View File
@@ -2,9 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
use crate::error::BandwidthControllerError;
use nym_coconut_interface::{Base58, Parameters};
use nym_coconut_interface::Base58;
use nym_credential_storage::storage::Storage;
use nym_credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES};
use nym_credentials::coconut::bandwidth::BandwidthVoucher;
use nym_credentials::coconut::utils::obtain_aggregate_signature;
use nym_crypto::asymmetric::{encryption, identity};
use nym_network_defaults::VOUCHER_INFO;
@@ -12,10 +12,8 @@ use nym_validator_client::coconut::all_coconut_api_clients;
use nym_validator_client::nyxd::contract_traits::CoconutBandwidthSigningClient;
use nym_validator_client::nyxd::contract_traits::DkgQueryClient;
use nym_validator_client::nyxd::Coin;
use nym_validator_client::nyxd::Hash;
use rand::rngs::OsRng;
use state::{KeyPair, State};
use std::str::FromStr;
use state::State;
pub mod state;
@@ -24,30 +22,29 @@ where
C: CoconutBandwidthSigningClient + Sync,
{
let mut rng = OsRng;
let signing_keypair = KeyPair::from(identity::KeyPair::new(&mut rng));
let encryption_keypair = KeyPair::from(encryption::KeyPair::new(&mut rng));
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
let signing_key = identity::PrivateKey::new(&mut rng);
let encryption_key = encryption::PrivateKey::new(&mut rng);
let params = BandwidthVoucher::default_parameters();
let voucher_value = amount.amount.to_string();
let tx_hash = client
.deposit(
amount,
String::from(VOUCHER_INFO),
signing_keypair.public_key.clone(),
encryption_keypair.public_key.clone(),
signing_key.public_key().to_base58_string(),
encryption_key.public_key().to_base58_string(),
None,
)
.await?
.transaction_hash
.to_string();
.transaction_hash;
let voucher = BandwidthVoucher::new(
&params,
voucher_value,
VOUCHER_INFO.to_string(),
Hash::from_str(&tx_hash).map_err(|_| BandwidthControllerError::InvalidTxHash)?,
identity::PrivateKey::from_base58_string(&signing_keypair.private_key)?,
encryption::PrivateKey::from_base58_string(&encryption_keypair.private_key)?,
tx_hash,
signing_key,
encryption_key,
);
let state = State { voucher, params };
@@ -2,32 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use nym_coconut_interface::Parameters;
use nym_credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES};
use nym_crypto::asymmetric::{encryption, identity};
pub(crate) struct KeyPair {
pub public_key: String,
pub private_key: String,
}
impl From<identity::KeyPair> for KeyPair {
fn from(kp: identity::KeyPair) -> Self {
Self {
public_key: kp.public_key().to_base58_string(),
private_key: kp.private_key().to_base58_string(),
}
}
}
impl From<encryption::KeyPair> for KeyPair {
fn from(kp: encryption::KeyPair) -> Self {
Self {
public_key: kp.public_key().to_base58_string(),
private_key: kp.private_key().to_base58_string(),
}
}
}
use nym_credentials::coconut::bandwidth::BandwidthVoucher;
pub struct State {
pub voucher: BandwidthVoucher,
@@ -38,7 +13,7 @@ impl State {
pub fn new(voucher: BandwidthVoucher) -> Self {
State {
voucher,
params: Parameters::new(TOTAL_ATTRIBUTES).unwrap(),
params: BandwidthVoucher::default_parameters(),
}
}
}
+9 -6
View File
@@ -7,6 +7,7 @@ use nym_credential_storage::storage::Storage;
use nym_validator_client::coconut::all_coconut_api_clients;
use nym_validator_client::nyxd::contract_traits::DkgQueryClient;
use std::str::FromStr;
use zeroize::Zeroizing;
use {
nym_coconut_interface::Base58,
nym_credentials::coconut::{
@@ -46,10 +47,12 @@ impl<C, St: Storage> BandwidthController<C, St> {
let voucher_value = u64::from_str(&bandwidth_credential.voucher_value)
.map_err(|_| StorageError::InconsistentData)?;
let voucher_info = bandwidth_credential.voucher_info.clone();
let serial_number =
nym_coconut_interface::Attribute::try_from_bs58(bandwidth_credential.serial_number)?;
let binding_number =
nym_coconut_interface::Attribute::try_from_bs58(bandwidth_credential.binding_number)?;
let serial_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58(
bandwidth_credential.serial_number,
)?);
let binding_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58(
bandwidth_credential.binding_number,
)?);
let signature =
nym_coconut_interface::Signature::try_from_bs58(bandwidth_credential.signature)?;
let epoch_id = u64::from_str(&bandwidth_credential.epoch_id)
@@ -64,8 +67,8 @@ impl<C, St: Storage> BandwidthController<C, St> {
prepare_for_spending(
voucher_value,
voucher_info,
serial_number,
binding_number,
&serial_number,
&binding_number,
epoch_id,
&signature,
&verification_key,
+2 -1
View File
@@ -35,9 +35,10 @@ opentelemetry = { version = "0.19.0", optional = true, features = ["rt-tokio"] }
[build-dependencies]
vergen = { version = "=7.4.3", default-features = false, features = [
vergen = { version = "=8.2.6", default-features = false, features = [
"build",
"git",
"gitcl",
"rustc",
"cargo",
] }
+8 -7
View File
@@ -1,13 +1,14 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::{vergen, Config};
use vergen::EmitBuilder;
fn main() {
let mut config = Config::default();
if std::env::var("DOCS_RS").is_ok() {
// If we don't have access to git information, such as in a docs.rs build, don't error
*config.git_mut().skip_if_error_mut() = true;
}
vergen(config).expect("failed to extract build metadata");
EmitBuilder::builder()
.all_build()
.all_git()
.all_rustc()
.all_cargo()
.emit()
.expect("failed to extract build metadata");
}
+10 -10
View File
@@ -40,9 +40,9 @@ pub struct BinaryBuildInformation {
/// Provides the rustc channel that was used for the build, for example `nightly`.
pub rustc_channel: &'static str,
// VERGEN_CARGO_PROFILE
/// Provides the cargo profile that was used for the build, for example `debug`.
pub cargo_profile: &'static str,
// VERGEN_CARGO_DEBUG
/// Provides the cargo debug mode that was used for the build.
pub cargo_debug: &'static str,
}
impl BinaryBuildInformation {
@@ -57,7 +57,7 @@ impl BinaryBuildInformation {
commit_branch: env!("VERGEN_GIT_BRANCH"),
rustc_version: env!("VERGEN_RUSTC_SEMVER"),
rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
cargo_profile: env!("VERGEN_CARGO_PROFILE"),
cargo_debug: env!("VERGEN_CARGO_DEBUG"),
}
}
@@ -71,7 +71,7 @@ impl BinaryBuildInformation {
commit_branch: self.commit_branch.to_owned(),
rustc_version: self.rustc_version.to_owned(),
rustc_channel: self.rustc_channel.to_owned(),
cargo_profile: self.cargo_profile.to_owned(),
cargo_debug: self.cargo_debug.to_owned(),
}
}
@@ -115,9 +115,9 @@ pub struct BinaryBuildInformationOwned {
/// Provides the rustc channel that was used for the build, for example `nightly`.
pub rustc_channel: String,
// VERGEN_CARGO_PROFILE
/// Provides the cargo profile that was used for the build, for example `debug`.
pub cargo_profile: String,
// VERGEN_CARGO_DEBUG
/// Provides the cargo debug mode that was used for the build.
pub cargo_debug: String,
}
impl Display for BinaryBuildInformationOwned {
@@ -151,8 +151,8 @@ impl Display for BinaryBuildInformationOwned {
self.rustc_version,
"rustc Channel:",
self.rustc_channel,
"cargo Profile:",
self.cargo_profile,
"cargo Debug:",
self.cargo_debug,
)
}
}
+3 -2
View File
@@ -4,6 +4,7 @@ version = "1.1.15"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021"
rust-version = "1.66"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -58,7 +59,7 @@ features = ["time"]
version = "0.20.1"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
version = "0.6.2"
workspace = true
features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]
optional = true
@@ -89,7 +90,7 @@ tempfile = "3.1.0"
[build-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
[features]
default = []
@@ -1,6 +1,8 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#![allow(unused_imports)]
use std::time::Duration;
pub use wasmtimer::{std::Instant, tokio::*};
@@ -127,7 +127,9 @@ impl ActionController {
.insert(frag_id, (Arc::new(pending_ack), None))
.is_some()
{
panic!("Tried to insert duplicate pending ack")
// This used to be a panic, however since we've seen this actually happen in the
// wild, let's not take the whole client (and possibly gateway) down because of it.
error!("Tried to insert duplicate pending ack! This should not be possible!")
}
}
}
@@ -3,6 +3,7 @@ name = "nym-gateway-client"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+3 -2
View File
@@ -3,14 +3,15 @@ name = "nym-mixnet-client"
version = "0.1.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
futures = { workspace = true }
log = { workspace = true }
tokio = { version = "1.24.1", features = ["time", "net", "rt"] }
tokio-util = { version = "0.7.4", features = ["codec"] }
tokio = { workspace = true, features = ["time", "net", "rt"] }
tokio-util = { workspace = true, features = ["codec"] }
# internal
nym-sphinx = { path = "../../nymsphinx" }
@@ -4,6 +4,7 @@ version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
rust-version = "1.56"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -42,6 +42,14 @@ pub struct Config {
nyxd_config: nyxd::Config,
}
impl TryFrom<NymNetworkDetails> for Config {
type Error = ValidatorClientError;
fn try_from(value: NymNetworkDetails) -> Result<Self, Self::Error> {
Config::try_from_nym_network_details(&value)
}
}
impl Config {
pub fn try_from_nym_network_details(
details: &NymNetworkDetails,
@@ -5,16 +5,24 @@ use crate::nym_api::error::NymAPIError;
use crate::nym_api::routes::{CORE_STATUS_COUNT, SINCE_ARG};
use async_trait::async_trait;
use http_api_client::{ApiClient, NO_PARAMS};
use nym_api_requests::coconut::{
BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse,
};
use nym_api_requests::models::{
ComputeRewardEstParam, DescribedGateway, GatewayBondAnnotated, GatewayCoreStatusResponse,
GatewayStatusReportResponse, GatewayUptimeHistoryResponse, InclusionProbabilityResponse,
MixNodeBondAnnotated, MixnodeCoreStatusResponse, MixnodeStatusReportResponse,
MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RewardEstimationResponse,
StakeSaturationResponse, UptimeResponse,
pub use nym_api_requests::{
coconut::{
models::{
EpochCredentialsResponse, IssuedCredential, IssuedCredentialBody,
IssuedCredentialResponse, IssuedCredentialsResponse,
},
BlindSignRequestBody, BlindedSignatureResponse, CredentialsRequestBody,
VerifyCredentialBody, VerifyCredentialResponse,
},
models::{
ComputeRewardEstParam, DescribedGateway, GatewayBondAnnotated, GatewayCoreStatusResponse,
GatewayStatusReportResponse, GatewayUptimeHistoryResponse, InclusionProbabilityResponse,
MixNodeBondAnnotated, MixnodeCoreStatusResponse, MixnodeStatusReportResponse,
MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RewardEstimationResponse,
StakeSaturationResponse, UptimeResponse,
},
};
pub use nym_coconut_dkg_common::types::EpochId;
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId};
use nym_name_service_common::response::NamesListResponse;
@@ -399,6 +407,60 @@ pub trait NymApiClientExt: ApiClient {
.await
}
async fn epoch_credentials(
&self,
dkg_epoch: EpochId,
) -> Result<EpochCredentialsResponse, NymAPIError> {
self.get_json(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_EPOCH_CREDENTIALS,
&dkg_epoch.to_string(),
],
NO_PARAMS,
)
.await
}
async fn issued_credential(
&self,
credential_id: i64,
) -> Result<IssuedCredentialResponse, NymAPIError> {
self.get_json(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_ISSUED_CREDENTIAL,
&credential_id.to_string(),
],
NO_PARAMS,
)
.await
}
async fn issued_credentials(
&self,
credential_ids: Vec<i64>,
) -> Result<IssuedCredentialsResponse, NymAPIError> {
self.post_json(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_ISSUED_CREDENTIALS,
],
NO_PARAMS,
&CredentialsRequestBody {
credential_ids,
pagination: None,
},
)
.await
}
async fn get_service_providers(&self) -> Result<ServicesListResponse, NymAPIError> {
log::trace!("Getting service providers");
self.get_json(&[routes::API_VERSION, routes::SERVICE_PROVIDERS], NO_PARAMS)
@@ -17,6 +17,9 @@ pub const BANDWIDTH: &str = "bandwidth";
pub const COCONUT_BLIND_SIGN: &str = "blind-sign";
pub const COCONUT_VERIFY_BANDWIDTH_CREDENTIAL: &str = "verify-bandwidth-credential";
pub const COCONUT_EPOCH_CREDENTIALS: &str = "epoch-credentials";
pub const COCONUT_ISSUED_CREDENTIAL: &str = "issued-credential";
pub const COCONUT_ISSUED_CREDENTIALS: &str = "issued-credentials";
pub const STATUS_ROUTES: &str = "status";
pub const MIXNODE: &str = "mixnode";
@@ -8,6 +8,8 @@ use cosmwasm_std::{Fraction, Uint128};
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::Div;
use std::str::FromStr;
use thiserror::Error;
#[derive(Serialize, Deserialize, Clone, Copy, Default, Debug, PartialEq, Eq)]
pub struct MismatchedDenoms;
@@ -126,6 +128,37 @@ impl From<CosmWasmCoin> for Coin {
}
}
// unfortunately cosmwasm didn't re-export this correct so we just redefine its
#[derive(Error, Debug, PartialEq, Eq)]
pub enum CoinFromStrError {
#[error("Missing denominator")]
MissingDenom,
#[error("Missing amount or non-digit characters in amount")]
MissingAmount,
#[error("Invalid amount: {0}")]
InvalidAmount(#[from] std::num::ParseIntError),
}
impl FromStr for Coin {
type Err = CoinFromStrError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let pos = s
.find(|c: char| !c.is_ascii_digit())
.ok_or(CoinFromStrError::MissingDenom)?;
let (amount, denom) = s.split_at(pos);
if amount.is_empty() {
return Err(CoinFromStrError::MissingAmount);
}
Ok(Coin {
amount: amount.parse::<u128>()?,
denom: denom.to_string(),
})
}
}
pub trait CoinConverter {
type Target;
@@ -32,7 +32,7 @@ pub trait CoconutBandwidthSigningClient {
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = CoconutBandwidthExecuteMsg::DepositFunds {
data: DepositData::new(info.to_string(), verification_key, encryption_key),
data: DepositData::new(info, verification_key, encryption_key),
};
self.execute_coconut_bandwidth_contract(
fee,
@@ -7,12 +7,12 @@ use crate::nyxd::error::NyxdError;
use crate::nyxd::CosmWasmClient;
use async_trait::async_trait;
use cosmrs::AccountId;
use nym_coconut_dkg_common::dealer::{
ContractDealing, DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse,
use nym_coconut_dkg_common::{
dealer::{ContractDealing, DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse},
msg::QueryMsg as DkgQueryMsg,
types::{DealerDetails, Epoch, EpochId, InitialReplacementData},
verification_key::{ContractVKShare, PagedVKSharesResponse},
};
use nym_coconut_dkg_common::msg::QueryMsg as DkgQueryMsg;
use nym_coconut_dkg_common::types::{DealerDetails, Epoch, EpochId, InitialReplacementData};
use nym_coconut_dkg_common::verification_key::{ContractVKShare, PagedVKSharesResponse};
use serde::Deserialize;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
@@ -6,8 +6,8 @@ use crate::nyxd::error::NyxdError;
use crate::nyxd::CosmWasmClient;
use async_trait::async_trait;
use cw3::{
ProposalListResponse, ProposalResponse, VoteListResponse, VoteResponse, VoterListResponse,
VoterResponse,
ProposalListResponse, ProposalResponse, VoteListResponse, VoteResponse, VoterDetail,
VoterListResponse, VoterResponse,
};
use cw_utils::ThresholdResponse;
use nym_multisig_contract_common::msg::QueryMsg as MultisigQueryMsg;
@@ -114,6 +114,26 @@ pub trait PagedMultisigQueryClient: MultisigQueryClient {
Ok(proposals)
}
async fn get_all_voters(&self) -> Result<Vec<VoterDetail>, NyxdError> {
let mut voters = Vec::new();
let mut start_after = None;
loop {
let mut paged_response = self.list_voters(start_after.take(), None).await?;
let last_voter = paged_response.voters.last().map(|prop| prop.addr.clone());
voters.append(&mut paged_response.voters);
if let Some(start_after_res) = last_voter {
start_after = Some(start_after_res)
} else {
break;
}
}
Ok(voters)
}
}
#[async_trait]
@@ -52,10 +52,6 @@ use wasmtimer::tokio::sleep;
pub const DEFAULT_BROADCAST_POLLING_RATE: Duration = Duration::from_secs(4);
pub const DEFAULT_BROADCAST_TIMEOUT: Duration = Duration::from_secs(60);
#[cfg(feature = "http-client")]
#[async_trait]
impl CosmWasmClient for cosmrs::rpc::HttpClient {}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait CosmWasmClient: TendermintRpcClient {
@@ -522,3 +518,7 @@ pub trait CosmWasmClient: TendermintRpcClient {
res.try_into()
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<T> CosmWasmClient for T where T: TendermintRpcClient {}
@@ -425,7 +425,7 @@ where
amount: amount.into_iter().map(Into::into).collect(),
}
.to_any()
.map_err(|_| NyxdError::SerializationError("MsgExecuteContract".to_owned()))
.map_err(|_| NyxdError::SerializationError("MsgSend".to_owned()))
})
.collect::<Result<_, _>>()?;
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient};
use crate::nyxd::cosmwasm_client::client_traits::SigningCosmWasmClient;
use crate::nyxd::error::NyxdError;
use crate::nyxd::{Config, GasPrice, Hash, Height};
use crate::rpc::TendermintRpcClient;
@@ -26,6 +26,7 @@ use cosmrs::rpc::{HttpClient, HttpClientUrl};
pub mod client_traits;
mod helpers;
pub mod logs;
pub mod module_traits;
pub mod types;
#[derive(Debug)]
@@ -329,14 +330,6 @@ where
}
}
#[async_trait]
impl<C, S> CosmWasmClient for MaybeSigningClient<C, S>
where
C: TendermintRpcClient + Send + Sync,
S: Send + Sync,
{
}
#[async_trait]
impl<C, S> SigningCosmWasmClient for MaybeSigningClient<C, S>
where
@@ -0,0 +1,8 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod slashing;
pub mod staking;
pub use staking::query::StakingQueryClient;
// pub use slashing::query
@@ -0,0 +1,4 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod query;
@@ -0,0 +1,2 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
@@ -0,0 +1,8 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod query;
pub use cosmrs::staking::{
QueryHistoricalInfoResponse, QueryValidatorResponse, QueryValidatorsResponse, Validator,
};
@@ -0,0 +1,78 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::{QueryHistoricalInfoResponse, QueryValidatorResponse, QueryValidatorsResponse};
use crate::nyxd::error::NyxdError;
use crate::nyxd::{CosmWasmClient, PageRequest};
use async_trait::async_trait;
use cosmrs::proto::cosmos::staking::v1beta1::{
QueryHistoricalInfoRequest as ProtoQueryHistoricalInfoRequest,
QueryHistoricalInfoResponse as ProtoQueryHistoricalInfoResponse,
QueryValidatorRequest as ProtoQueryValidatorRequest,
QueryValidatorResponse as ProtoQueryValidatorResponse,
QueryValidatorsRequest as ProtoQueryValidatorsRequest,
QueryValidatorsResponse as ProtoQueryValidatorsResponse,
};
use cosmrs::staking::{QueryHistoricalInfoRequest, QueryValidatorRequest, QueryValidatorsRequest};
use cosmrs::AccountId;
// TODO: change trait restriction from `CosmWasmClient` to `TendermintRpcClient`
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait StakingQueryClient: CosmWasmClient {
async fn historical_info(&self, height: i64) -> Result<QueryHistoricalInfoResponse, NyxdError> {
let path = Some("/cosmos.staking.v1beta1.Query/HistoricalInfo".to_owned());
let req = QueryHistoricalInfoRequest { height };
let res = self
.make_abci_query::<ProtoQueryHistoricalInfoRequest, ProtoQueryHistoricalInfoResponse>(
path,
req.into(),
)
.await?;
Ok(res.try_into()?)
}
async fn validator(
&self,
validator_addr: AccountId,
) -> Result<QueryValidatorResponse, NyxdError> {
let path = Some("/cosmos.staking.v1beta1.Query/Validator".to_owned());
let req = QueryValidatorRequest { validator_addr };
let res = self
.make_abci_query::<ProtoQueryValidatorRequest, ProtoQueryValidatorResponse>(
path,
req.into(),
)
.await?;
Ok(res.try_into()?)
}
async fn validators(
&self,
status: String,
pagination: Option<PageRequest>,
) -> Result<QueryValidatorsResponse, NyxdError> {
let path = Some("/cosmos.staking.v1beta1.Query/Validators".to_owned());
let req = QueryValidatorsRequest { status, pagination };
let res = self
.make_abci_query::<ProtoQueryValidatorsRequest, ProtoQueryValidatorsResponse>(
path,
req.into(),
)
.await?;
Ok(res.try_into()?)
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<T> StakingQueryClient for T where T: CosmWasmClient {}
@@ -0,0 +1,13 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nyxd::TxResponse;
pub fn find_tx_attribute(tx: &TxResponse, event_type: &str, attribute_key: &str) -> Option<String> {
let event = tx.tx_result.events.iter().find(|e| e.kind == event_type)?;
let attribute = event
.attributes
.iter()
.find(|attr| attr.key == attribute_key)?;
Some(attribute.value.clone())
}
@@ -29,31 +29,41 @@ use tendermint_rpc::endpoint::*;
use tendermint_rpc::{Error as TendermintRpcError, Order};
use url::Url;
pub use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient};
pub use crate::nyxd::fee::Fee;
pub use crate::nyxd::{
cosmwasm_client::{
client_traits::{CosmWasmClient, SigningCosmWasmClient},
module_traits::{self, StakingQueryClient},
},
fee::Fee,
};
pub use crate::rpc::TendermintRpcClient;
pub use coin::Coin;
pub use cosmrs::bank::MsgSend;
pub use cosmrs::tendermint::abci::{
response::DeliverTx, types::ExecTxResult, Event, EventAttribute,
pub use cosmrs::{
bank::MsgSend,
bip32,
crypto::PublicKey,
query::{PageRequest, PageResponse},
tendermint::{
abci::{response::DeliverTx, types::ExecTxResult, Event, EventAttribute},
block::Height,
hash::{self, Algorithm, Hash},
validator::Info as TendermintValidatorInfo,
Time as TendermintTime,
},
tx::{self, Msg},
AccountId, Any, Coin as CosmosCoin, Denom, Gas,
};
pub use cosmrs::tendermint::block::Height;
pub use cosmrs::tendermint::hash::{self, Algorithm, Hash};
pub use cosmrs::tendermint::validator::Info as TendermintValidatorInfo;
pub use cosmrs::tendermint::Time as TendermintTime;
pub use cosmrs::tx::Msg;
pub use cosmrs::tx::{self};
pub use cosmrs::Coin as CosmosCoin;
pub use cosmrs::Gas;
pub use cosmrs::{bip32, AccountId, Denom};
pub use cosmwasm_std::Coin as CosmWasmCoin;
pub use cw2;
pub use cw3;
pub use cw4;
pub use cw_controllers;
pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment};
pub use tendermint_rpc::{
endpoint::{tx::Response as TxResponse, validators::Response as ValidatorResponse},
query::Query,
Paging,
Paging, Request, Response, SimpleRequest,
};
pub use tendermint_rpc::{Request, Response, SimpleRequest};
#[cfg(feature = "http-client")]
use crate::http_client;
@@ -67,6 +77,7 @@ pub mod contract_traits;
pub mod cosmwasm_client;
pub mod error;
pub mod fee;
pub mod helpers;
#[derive(Debug, Clone)]
pub struct Config {
@@ -92,6 +103,14 @@ impl Config {
}
}
impl TryFrom<NymNetworkDetails> for Config {
type Error = NyxdError;
fn try_from(value: NymNetworkDetails) -> Result<Self, Self::Error> {
Config::try_from_nym_network_details(&value)
}
}
#[derive(Debug)]
pub struct NyxdClient<C, S = NoSigner> {
client: MaybeSigningClient<C, S>,
@@ -723,7 +742,7 @@ where
where
H: Into<Height> + Send,
{
self.client.validators(height, paging).await
TendermintRpcClient::validators(&self.client, height, paging).await
}
async fn latest_consensus_params(
@@ -798,14 +817,6 @@ where
}
}
#[async_trait]
impl<C, S> CosmWasmClient for NyxdClient<C, S>
where
C: TendermintRpcClient + Send + Sync,
S: Send + Sync,
{
}
impl<C, S> OfflineSigner for NyxdClient<C, S>
where
S: OfflineSigner,
+1
View File
@@ -3,6 +3,7 @@ name = "nym-coconut-interface"
version = "0.1.0"
edition = "2021"
description = "Crutch library until there is proper SerDe support for coconut structs"
license.workspace = true
[dependencies]
bs58 = "0.4.0"
+12 -10
View File
@@ -21,10 +21,14 @@ pub use nym_coconut::{
pub struct Credential {
#[getset(get = "pub")]
n_params: u32,
#[getset(get = "pub")]
theta: Theta,
voucher_value: u64,
voucher_info: String,
#[getset(get = "pub")]
epoch_id: u64,
}
@@ -64,14 +68,12 @@ impl Credential {
pub fn verify(&self, verification_key: &VerificationKey) -> bool {
let params = Parameters::new(self.n_params).unwrap();
let public_attributes = [
self.voucher_value.to_string().as_bytes(),
self.voucher_info.as_bytes(),
]
.iter()
.map(hash_to_scalar)
.collect::<Vec<Attribute>>();
nym_coconut::verify_credential(&params, verification_key, &self.theta, &public_attributes)
let hashed_value = hash_to_scalar(self.voucher_value.to_string());
let hashed_info = hash_to_scalar(&self.voucher_info);
let public_attributes = &[&hashed_value, &hashed_info];
nym_coconut::verify_credential(&params, verification_key, &self.theta, public_attributes)
}
pub fn as_bytes(&self) -> Vec<u8> {
@@ -180,8 +182,8 @@ mod tests {
&params,
&verification_key,
&signature,
serial_number,
binding_number,
&serial_number,
&binding_number,
)
.unwrap();
let credential = Credential::new(4, theta, voucher_value, voucher_info, 42);
+1
View File
@@ -3,6 +3,7 @@ name = "nym-cli-commands"
version = "1.0.0"
authors.workspace = true
edition = "2021"
license.workspace = true
[dependencies]
anyhow = { workspace = true }
@@ -26,6 +26,10 @@ pub struct Args {
}
pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
if args.amount == 0 {
bail!("did not specify credential amount")
}
let loaded = CommonConfigsWrapper::try_load(args.client_config)?;
if let Ok(id) = loaded.try_get_id() {
+2 -1
View File
@@ -3,6 +3,7 @@ name = "nym-config"
version = "0.1.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -17,4 +18,4 @@ url = { workspace = true }
nym-network-defaults = { path = "../network-defaults" }
[features]
default = ["dirs"]
default = ["dirs"]
+1 -1
View File
@@ -73,7 +73,7 @@ where
P: AsRef<Path>,
{
let path = path.as_ref();
log::debug!("trying to save config file to {}", path.display());
log::info!("saving config file to {}", path.display());
if let Some(parent) = path.parent() {
create_dir_all(parent)?;
@@ -2,6 +2,7 @@
name = "nym-coconut-bandwidth-contract-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -12,4 +13,4 @@ cw2 = { workspace = true, optional = true }
nym-multisig-contract-common = { path = "../multisig-contract" }
[features]
schema = ["cw2"]
schema = ["cw2"]
@@ -4,6 +4,9 @@
// event types
pub const DEPOSITED_FUNDS_EVENT_TYPE: &str = "deposited-funds";
// a 'wasm-' prefix is added to all cosmwasm events
pub const COSMWASM_DEPOSITED_FUNDS_EVENT_TYPE: &str = "wasm-deposited-funds";
// attributes that are used in multiple places
pub const DEPOSIT_VALUE: &str = "deposit-value";
pub const DEPOSIT_INFO: &str = "deposit-info";
@@ -2,6 +2,7 @@
name = "nym-coconut-dkg-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -14,4 +15,4 @@ contracts-common = { path = "../contracts-common", package = "nym-contracts-comm
nym-multisig-contract-common = { path = "../multisig-contract" }
[features]
schema = []
schema = []
@@ -174,17 +174,19 @@ impl Display for EpochState {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
EpochState::PublicKeySubmission { resharing } => {
write!(f, "PublicKeySubmission with resharing {resharing}")
write!(f, "PublicKeySubmission (resharing: {resharing})")
}
EpochState::DealingExchange { resharing } => {
write!(f, "DealingExchange (resharing: {resharing})")
}
EpochState::DealingExchange { resharing } => write!(f, "DealingExchange {resharing}"),
EpochState::VerificationKeySubmission { resharing } => {
write!(f, "VerificationKeySubmission with resharing {resharing}")
write!(f, "VerificationKeySubmission (resharing: {resharing})")
}
EpochState::VerificationKeyValidation { resharing } => {
write!(f, "VerificationKeyValidation with resharing {resharing}")
write!(f, "VerificationKeyValidation (resharing: {resharing})")
}
EpochState::VerificationKeyFinalization { resharing } => {
write!(f, "VerificationKeyFinalization with resharing {resharing}")
write!(f, "VerificationKeyFinalization (resharing: {resharing})")
}
EpochState::InProgress => write!(f, "InProgress"),
}
@@ -2,6 +2,7 @@
name = "nym-ephemera-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -13,4 +14,4 @@ cw-utils = { workspace = true }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common" }
[features]
schema = []
schema = []
@@ -2,6 +2,7 @@
name = "nym-group-contract-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -2,6 +2,7 @@
name = "nym-multisig-contract-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -2,6 +2,7 @@
name = "nym-name-service-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -16,4 +17,4 @@ serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
[features]
schema = ["cw2"]
schema = ["cw2"]
@@ -2,6 +2,7 @@
name = "nym-service-provider-directory-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -15,4 +16,4 @@ nym-contracts-common = { path = "../contracts-common", version = "0.5.0" }
thiserror = { workspace = true }
[features]
schema = ["cw2"]
schema = ["cw2"]
+4 -3
View File
@@ -2,6 +2,7 @@
name = "nym-credential-storage"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -13,14 +14,14 @@ thiserror = { workspace = true }
tokio = { version = "1.24.1", features = ["sync"]}
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
version = "0.5"
workspace = true
features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
version = "1.24.1"
workspace = true
features = [ "rt-multi-thread", "net", "signal", "fs" ]
[build-dependencies]
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
+1
View File
@@ -2,6 +2,7 @@
name = "nym-credential-utils"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+4 -2
View File
@@ -2,18 +2,20 @@
name = "nym-credentials"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bls12_381 = { version = "0.5", default-features = false, features = ["pairings", "alloc", "experimental"] }
bls12_381 = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] }
cosmrs = { workspace = true }
thiserror = { workspace = true }
log = { workspace = true }
zeroize = { workspace = true }
# I guess temporarily until we get serde support in coconut up and running
nym-coconut-interface = { path = "../coconut-interface" }
nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "symmetric", "hashing"] }
nym-crypto = { path = "../crypto", features = ["rand", "asymmetric"] }
nym-api-requests = { path = "../../nym-api/nym-api-requests" }
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
+93 -51
View File
@@ -13,38 +13,60 @@ use nym_coconut_interface::{
PrivateAttribute, PublicAttribute, Signature, VerificationKey,
};
use nym_crypto::asymmetric::{encryption, identity};
use zeroize::{Zeroize, ZeroizeOnDrop};
use super::utils::prepare_credential_for_spending;
use crate::error::Error;
pub const PUBLIC_ATTRIBUTES: u32 = 2;
pub const PRIVATE_ATTRIBUTES: u32 = 2;
pub const TOTAL_ATTRIBUTES: u32 = PUBLIC_ATTRIBUTES + PRIVATE_ATTRIBUTES;
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct BandwidthVoucher {
// a random secret value generated by the client used for double-spending detection
// private attributes
/// a random secret value generated by the client used for double-spending detection
serial_number: PrivateAttribute,
// a random secret value generated by the client used to bind multiple credentials together
/// a random secret value generated by the client used to bind multiple credentials together
binding_number: PrivateAttribute,
// the value (e.g., bandwidth) encoded in this voucher
voucher_value: PublicAttribute,
// the plain text value (e.g., bandwidth) encoded in this voucher
// public atttributes:
/// the plain text value (e.g., bandwidth) encoded in this voucher
// TODO: in another PR change the value from `"1000"` to `"1000unym"`
voucher_value_plain: String,
// a field with public information, e.g., type of voucher, interval etc.
voucher_info: PublicAttribute,
// the plain text information
/// the plain text information
voucher_info_plain: String,
// the hash of the deposit transaction
/// the precomputed value (e.g., bandwidth) encoded in this voucher
_voucher_value_prehashed: PublicAttribute,
/// the precomputed field with public information, e.g., type of voucher, interval etc.
_voucher_info_prehashed: PublicAttribute,
/// the hash of the deposit transaction
#[zeroize(skip)]
tx_hash: Hash,
// base58 encoded private key ensuring the depositer requested these attributes
/// base58 encoded private key ensuring the depositer requested these attributes
signing_key: identity::PrivateKey,
// base58 encoded private key ensuring only this client receives the signature share
encryption_key: encryption::PrivateKey,
/// base58 encoded private key ensuring only this client receives the signature share
unused_ed25519: encryption::PrivateKey,
pedersen_commitments_openings: Vec<Attribute>,
#[zeroize(skip)]
blind_sign_request: BlindSignRequest,
}
impl BandwidthVoucher {
pub const PUBLIC_ATTRIBUTES: u32 = 2;
pub const PRIVATE_ATTRIBUTES: u32 = 2;
pub const ENCODED_ATTRIBUTES: u32 = 4;
pub fn default_parameters() -> Parameters {
// safety: the unwrap is fine here as Self::ENCODED_ATTRIBUTES is non-zero
Parameters::new(Self::ENCODED_ATTRIBUTES).unwrap()
}
pub fn new(
params: &Parameters,
voucher_value: String,
@@ -57,24 +79,26 @@ impl BandwidthVoucher {
let binding_number = params.random_scalar();
let voucher_value_plain = voucher_value.clone();
let voucher_info_plain = voucher_info.clone();
let voucher_value = hash_to_scalar(voucher_value.as_bytes());
let voucher_info = hash_to_scalar(voucher_info.as_bytes());
let _voucher_value_prehashed = hash_to_scalar(voucher_value);
let _voucher_info_prehashed = hash_to_scalar(voucher_info);
let (pedersen_commitments_openings, blind_sign_request) = prepare_blind_sign(
params,
&[serial_number, binding_number],
&[voucher_value, voucher_info],
&[&serial_number, &binding_number],
&[&_voucher_value_prehashed, &_voucher_info_prehashed],
)
.unwrap();
BandwidthVoucher {
serial_number,
binding_number,
voucher_value,
_voucher_value_prehashed,
voucher_value_plain,
voucher_info,
_voucher_info_prehashed,
voucher_info_plain,
tx_hash,
signing_key,
encryption_key,
unused_ed25519: encryption_key,
pedersen_commitments_openings,
blind_sign_request,
}
@@ -87,7 +111,7 @@ impl BandwidthVoucher {
let voucher_info_plain_b = self.voucher_info_plain.as_bytes();
let tx_hash_b = self.tx_hash.as_bytes();
let signing_key_b = self.signing_key.to_bytes();
let encryption_key_b = self.encryption_key.to_bytes();
let encryption_key_b = self.unused_ed25519.to_bytes();
let blind_sign_request_b = self.blind_sign_request.to_bytes();
let mut ret = Vec::new();
@@ -171,13 +195,13 @@ impl BandwidthVoucher {
bytes[var_length_pointer..var_length_pointer + voucher_value_plain_no].to_vec(),
)
.or_else(utf_err)?;
let voucher_value = hash_to_scalar(&voucher_value_plain);
let _voucher_value_prehashed = hash_to_scalar(&voucher_value_plain);
var_length_pointer += voucher_value_plain_no;
let voucher_info_plain = String::from_utf8(
bytes[var_length_pointer..var_length_pointer + voucher_info_plain_no].to_vec(),
)
.or_else(utf_err)?;
let voucher_info = hash_to_scalar(&voucher_info_plain);
let _voucher_info_prehashed = hash_to_scalar(&voucher_info_plain);
var_length_pointer += voucher_info_plain_no;
let blind_sign_request = BlindSignRequest::from_bytes(
&bytes[var_length_pointer..var_length_pointer + blind_sign_request_no],
@@ -196,36 +220,43 @@ impl BandwidthVoucher {
Ok(Self {
serial_number,
binding_number,
voucher_value,
_voucher_value_prehashed,
voucher_value_plain,
voucher_info,
_voucher_info_prehashed,
voucher_info_plain,
tx_hash,
signing_key,
encryption_key,
unused_ed25519: encryption_key,
pedersen_commitments_openings,
blind_sign_request,
})
}
/// Check if the plain values correspond to the PublicAttributes
pub fn verify_against_plain(values: &[PublicAttribute], plain_values: &[String]) -> bool {
pub fn verify_against_plain(values: &[&PublicAttribute], plain_values: &[String]) -> bool {
values.len() == 2
&& plain_values.len() == 2
&& values[0] == hash_to_scalar(&plain_values[0])
&& values[1] == hash_to_scalar(&plain_values[1])
&& values[0] == &hash_to_scalar(&plain_values[0])
&& values[1] == &hash_to_scalar(&plain_values[1])
}
pub fn tx_hash(&self) -> &Hash {
&self.tx_hash
pub fn tx_hash(&self) -> Hash {
self.tx_hash
}
pub fn get_public_attributes(&self) -> Vec<PublicAttribute> {
vec![self.voucher_value, self.voucher_info]
pub fn get_public_attributes(&self) -> Vec<&PublicAttribute> {
vec![
&self._voucher_value_prehashed,
&self._voucher_info_prehashed,
]
}
pub fn identity_key(&self) -> &identity::PrivateKey {
&self.signing_key
}
pub fn encryption_key(&self) -> &encryption::PrivateKey {
&self.encryption_key
&self.unused_ed25519
}
pub fn pedersen_commitments_openings(&self) -> &Vec<Attribute> {
@@ -247,27 +278,32 @@ impl BandwidthVoucher {
]
}
pub fn get_private_attributes(&self) -> Vec<PrivateAttribute> {
vec![self.serial_number, self.binding_number]
pub fn get_private_attributes(&self) -> Vec<&PrivateAttribute> {
vec![&self.serial_number, &self.binding_number]
}
pub fn sign(&self, request: &BlindSignRequest) -> identity::Signature {
pub fn signable_plaintext(request: &BlindSignRequest, tx_hash: Hash) -> Vec<u8> {
let mut message = request.to_bytes();
message.extend_from_slice(self.tx_hash.to_string().as_bytes());
self.signing_key.sign(&message)
message.extend_from_slice(tx_hash.as_bytes());
message
}
pub fn sign(&self) -> identity::Signature {
let message = Self::signable_plaintext(&self.blind_sign_request, self.tx_hash);
self.signing_key.sign(message)
}
}
pub fn prepare_for_spending(
voucher_value: u64,
voucher_info: String,
serial_number: PrivateAttribute,
binding_number: PrivateAttribute,
serial_number: &PrivateAttribute,
binding_number: &PrivateAttribute,
epoch_id: u64,
signature: &Signature,
verification_key: &VerificationKey,
) -> Result<Credential, Error> {
let params = Parameters::new(TOTAL_ATTRIBUTES)?;
let params = Parameters::new(BandwidthVoucher::ENCODED_ATTRIBUTES)?;
prepare_credential_for_spending(
&params,
@@ -316,24 +352,30 @@ mod test {
let deserialized_voucher = BandwidthVoucher::try_from_bytes(&bytes).unwrap();
assert_eq!(voucher.serial_number, deserialized_voucher.serial_number);
assert_eq!(voucher.binding_number, deserialized_voucher.binding_number);
assert_eq!(voucher.voucher_value, deserialized_voucher.voucher_value);
assert_eq!(
voucher.voucher_value_plain,
deserialized_voucher.voucher_value_plain
);
assert_eq!(voucher.voucher_info, deserialized_voucher.voucher_info);
assert_eq!(
voucher.voucher_info_plain,
deserialized_voucher.voucher_info_plain
);
assert_eq!(
voucher._voucher_value_prehashed,
deserialized_voucher._voucher_value_prehashed
);
assert_eq!(
voucher._voucher_info_prehashed,
deserialized_voucher._voucher_info_prehashed
);
assert_eq!(voucher.tx_hash, deserialized_voucher.tx_hash);
assert_eq!(
voucher.signing_key.to_string(),
deserialized_voucher.signing_key.to_string()
);
assert_eq!(
voucher.encryption_key.to_string(),
deserialized_voucher.encryption_key.to_string()
voucher.unused_ed25519.to_string(),
deserialized_voucher.unused_ed25519.to_string()
);
assert_eq!(
voucher.pedersen_commitments_openings,
@@ -371,11 +413,11 @@ mod test {
]
));
assert!(!BandwidthVoucher::verify_against_plain(
&[voucher.get_public_attributes()[0], Attribute::one()],
&[voucher.get_public_attributes()[0], &Attribute::one()],
&voucher.get_public_attributes_plain()
));
assert!(!BandwidthVoucher::verify_against_plain(
&[Attribute::one(), voucher.get_public_attributes()[1]],
&[&Attribute::one(), voucher.get_public_attributes()[1]],
&voucher.get_public_attributes_plain()
));
assert!(BandwidthVoucher::verify_against_plain(
-1
View File
@@ -2,5 +2,4 @@
// SPDX-License-Identifier: Apache-2.0
pub mod bandwidth;
pub mod params;
pub mod utils;
-15
View File
@@ -1,15 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use nym_crypto::aes::Aes128;
use nym_crypto::blake3;
use nym_crypto::ctr;
type Aes128Ctr = ctr::Ctr64LE<Aes128>;
/// Hashing algorithm used during hkdf for ephemeral shared key generation per blinded signature
/// response encryption.
pub type NymApiCredentialHkdfAlgorithm = blake3::Hasher;
/// Encryption algorithm used for end-to-end encryption of blinded signature response
pub type NymApiCredentialEncryptionAlgorithm = Aes128Ctr;
+22 -39
View File
@@ -1,18 +1,14 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::coconut::bandwidth::{BandwidthVoucher, PRIVATE_ATTRIBUTES, PUBLIC_ATTRIBUTES};
use crate::coconut::params::{NymApiCredentialEncryptionAlgorithm, NymApiCredentialHkdfAlgorithm};
use crate::coconut::bandwidth::BandwidthVoucher;
use crate::error::Error;
use log::{debug, warn};
use nym_api_requests::coconut::BlindSignRequestBody;
use nym_coconut_interface::{
aggregate_signature_shares, aggregate_verification_keys, prove_bandwidth_credential, Attribute,
BlindedSignature, Credential, Parameters, Signature, SignatureShare, VerificationKey,
Credential, Parameters, Signature, SignatureShare, VerificationKey,
};
use nym_crypto::asymmetric::encryption::PublicKey;
use nym_crypto::shared_key::recompute_shared_key;
use nym_crypto::symmetric::stream_cipher;
use nym_validator_client::client::CoconutApiClient;
pub async fn obtain_aggregate_verification_key(
@@ -36,47 +32,34 @@ pub async fn obtain_aggregate_verification_key(
async fn obtain_partial_credential(
params: &Parameters,
attributes: &BandwidthVoucher,
voucher: &BandwidthVoucher,
client: &nym_validator_client::client::NymApiClient,
validator_vk: &VerificationKey,
) -> Result<Signature, Error> {
let public_attributes = attributes.get_public_attributes();
let public_attributes_plain = attributes.get_public_attributes_plain();
let private_attributes = attributes.get_private_attributes();
let blind_sign_request = attributes.blind_sign_request();
let public_attributes_plain = voucher.get_public_attributes_plain();
let blind_sign_request = voucher.blind_sign_request();
let request_signature = voucher.sign();
let blind_sign_request_body = BlindSignRequestBody::new(
blind_sign_request,
attributes.tx_hash().to_string(),
attributes.sign(blind_sign_request).to_base58_string(),
&public_attributes,
blind_sign_request.clone(),
voucher.tx_hash(),
request_signature,
public_attributes_plain,
(public_attributes.len() + private_attributes.len()) as u32,
);
let response = client.blind_sign(&blind_sign_request_body).await?;
let encrypted_signature = response.encrypted_signature;
let remote_key = PublicKey::from_bytes(&response.remote_key)?;
let encryption_key = recompute_shared_key::<
NymApiCredentialEncryptionAlgorithm,
NymApiCredentialHkdfAlgorithm,
>(&remote_key, attributes.encryption_key());
let zero_iv = stream_cipher::zero_iv::<NymApiCredentialEncryptionAlgorithm>();
let blinded_signature_bytes = stream_cipher::decrypt::<NymApiCredentialEncryptionAlgorithm>(
&encryption_key,
&zero_iv,
&encrypted_signature,
);
let blinded_signature = response.blinded_signature;
let blinded_signature = BlindedSignature::from_bytes(&blinded_signature_bytes)?;
let public_attributes = voucher.get_public_attributes();
let private_attributes = voucher.get_private_attributes();
let unblinded_signature = blinded_signature.unblind(
let unblinded_signature = blinded_signature.unblind_and_verify(
params,
validator_vk,
&private_attributes,
&public_attributes,
&blind_sign_request.get_commitment_hash(),
attributes.pedersen_commitments_openings(),
voucher.pedersen_commitments_openings(),
)?;
Ok(unblinded_signature)
@@ -84,16 +67,13 @@ async fn obtain_partial_credential(
pub async fn obtain_aggregate_signature(
params: &Parameters,
attributes: &BandwidthVoucher,
voucher: &BandwidthVoucher,
coconut_api_clients: &[CoconutApiClient],
threshold: u64,
) -> Result<Signature, Error> {
if coconut_api_clients.is_empty() {
return Err(Error::NoValidatorsAvailable);
}
let public_attributes = attributes.get_public_attributes();
let private_attributes = attributes.get_private_attributes();
let mut shares = Vec::with_capacity(coconut_api_clients.len());
let validators_partial_vks: Vec<_> = coconut_api_clients
.iter()
@@ -114,7 +94,7 @@ pub async fn obtain_aggregate_signature(
match obtain_partial_credential(
params,
attributes,
voucher,
&coconut_api_client.api_client,
&coconut_api_client.verification_key,
)
@@ -136,6 +116,9 @@ pub async fn obtain_aggregate_signature(
return Err(Error::NotEnoughShares);
}
let public_attributes = voucher.get_public_attributes();
let private_attributes = voucher.get_private_attributes();
let mut attributes = Vec::with_capacity(private_attributes.len() + public_attributes.len());
attributes.extend_from_slice(&private_attributes);
attributes.extend_from_slice(&public_attributes);
@@ -150,8 +133,8 @@ pub fn prepare_credential_for_spending(
params: &Parameters,
voucher_value: u64,
voucher_info: String,
serial_number: Attribute,
binding_number: Attribute,
serial_number: &Attribute,
binding_number: &Attribute,
epoch_id: u64,
signature: &Signature,
verification_key: &VerificationKey,
@@ -165,7 +148,7 @@ pub fn prepare_credential_for_spending(
)?;
Ok(Credential::new(
PUBLIC_ATTRIBUTES + PRIVATE_ATTRIBUTES,
BandwidthVoucher::ENCODED_ATTRIBUTES,
theta,
voucher_value,
voucher_info,
@@ -201,6 +201,17 @@ impl<'a> From<&'a PrivateKey> for PublicKey {
}
impl PrivateKey {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let x25519_secret = x25519_dalek::StaticSecret::new(rng);
PrivateKey(x25519_secret)
}
pub fn public_key(&self) -> PublicKey {
self.into()
}
pub fn to_bytes(&self) -> [u8; PRIVATE_KEY_SIZE] {
self.0.to_bytes()
}
+23 -3
View File
@@ -5,13 +5,14 @@ pub use ed25519_dalek::ed25519::signature::Signature as SignatureTrait;
pub use ed25519_dalek::SignatureError;
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
#[cfg(feature = "sphinx")]
use nym_sphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH};
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;
use thiserror::Error;
use zeroize::{Zeroize, ZeroizeOnDrop};
#[cfg(feature = "sphinx")]
use nym_sphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH};
#[cfg(feature = "rand")]
use rand::{CryptoRng, RngCore};
#[cfg(feature = "serde")]
@@ -224,6 +225,17 @@ impl<'a> From<&'a PrivateKey> for PublicKey {
}
impl PrivateKey {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let ed25519_secret = ed25519_dalek::SecretKey::generate(rng);
PrivateKey(ed25519_secret)
}
pub fn public_key(&self) -> PublicKey {
self.into()
}
pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
self.0.to_bytes()
}
@@ -295,7 +307,7 @@ impl PemStorableKey for PrivateKey {
}
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Signature(ed25519_dalek::Signature);
impl Signature {
@@ -319,6 +331,14 @@ impl Signature {
}
}
impl FromStr for Signature {
type Err = Ed25519RecoveryError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Signature::from_base58_string(s)
}
}
#[cfg(feature = "serde")]
impl Serialize for Signature {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+4 -3
View File
@@ -3,6 +3,7 @@ name = "nym-dkg"
version = "0.1.0"
edition = "2021"
resolver = "2"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -11,7 +12,7 @@ bitvec = "1.0.0"
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch ="gt-serialisation", default-features = false, features = ["alloc", "pairings", "experimental", "zeroize"] }
bls12_381 = { workspace = true, default-features = false, features = ["alloc", "pairings", "experimental", "zeroize"] }
nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common", optional = true }
bs58 = "0.4"
@@ -29,11 +30,11 @@ zeroize = { workspace = true, features = ["zeroize_derive"] }
nym-pemstore = { path = "../pemstore" }
[dependencies.group]
version = "0.11"
workspace = true
default-features = false
[dependencies.ff]
version = "0.11"
workspace = true
default-features = false
[dev-dependencies]
+1
View File
@@ -2,6 +2,7 @@
name = "nym-execute"
version = "0.1.0"
edition = "2021"
license.workspace = true
[lib]
proc-macro = true
+63
View File
@@ -81,6 +81,15 @@ ExitPolicy accept6 *6:119
ExitPolicy accept *4:120
ExitPolicy reject6 [FC00::]/7:*
# Portless
ExitPolicy accept *:0
ExitPolicy accept *4:0
ExitPolicy accept *6:0
ExitPolicy reject *:0
ExitPolicy reject *4:0
ExitPolicy reject *6:0
#ExitPolicy accept *:8080 #and another comment here
ExitPolicy reject FE80:0000:0000:0000:0202:B3FF:FE1E:8329:*
@@ -184,6 +193,60 @@ ExitPolicy reject *:*
},
);
// ExitPolicy accept *:0
expected.push(
Accept,
AddressPortPattern {
ip_pattern: IpPattern::Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy accept *4:0
expected.push(
Accept,
AddressPortPattern {
ip_pattern: IpPattern::V4Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy accept *6:0
expected.push(
Accept,
AddressPortPattern {
ip_pattern: IpPattern::V6Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy reject *:0
expected.push(
Reject,
AddressPortPattern {
ip_pattern: IpPattern::Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy reject *4:0
expected.push(
Reject,
AddressPortPattern {
ip_pattern: IpPattern::V4Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy reject *6:0
expected.push(
Reject,
AddressPortPattern {
ip_pattern: IpPattern::V6Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy FE80:0000:0000:0000:0202:B3FF:FE1E:8329:*
expected.push(
Reject,
+37 -14
View File
@@ -264,7 +264,13 @@ mod stringified_ip_pattern {
impl AddressPortPattern {
/// Return true iff this pattern matches a given address and port.
pub fn matches(&self, addr: &IpAddr, port: u16) -> bool {
self.ip_pattern.matches(addr) && self.ports.contains(port)
// For backward compatibility, we treat port 0 as a wildcard until all gateways have
// upgraded, at which point we can add *:0 to the policy list.
if port == 0 {
self.ip_pattern.matches(addr)
} else {
self.ip_pattern.matches(addr) && self.ports.contains(port)
}
}
/// As matches, but accept a SocketAddr.
@@ -395,19 +401,9 @@ fn parse_addr(s: &str) -> Result<IpAddr, PolicyError> {
})
}
/// Helper: try to parse a port making sure it's non-zero
fn parse_port(s: &str) -> Result<u16, PolicyError> {
let port = s
.parse::<u16>()
.map_err(|_| PolicyError::InvalidPort { raw: s.to_string() })?;
if port == 0 {
Err(PolicyError::InvalidPort {
raw: port.to_string(),
})
} else {
Ok(port)
}
s.parse::<u16>()
.map_err(|_| PolicyError::InvalidPort { raw: s.to_string() })
}
impl FromStr for IpPattern {
@@ -494,6 +490,10 @@ impl PortRange {
PortRange::new_unchecked(1, 65535)
}
pub fn new_zero() -> Self {
PortRange { start: 0, end: 0 }
}
/// Create a new PortRange.
///
/// The Portrange contains all ports between `start` and `end` inclusive.
@@ -574,6 +574,7 @@ mod test {
check("marzipan:80");
check("1.2.3.4:90-80");
check("1.2.3.4:0-80");
check("1.2.3.4/100:8888");
check("[1.2.3.4]/16:80");
check("[::1]/130:8888");
@@ -612,6 +613,22 @@ mod test {
check("0.0.0.0/0:*", &["127.0.0.1:80"], &["[f00b::]:80"]);
check("[::]/0:*", &["[f00b::]:80"], &["127.0.0.1:80"]);
check(
"*:0",
&["1.2.3.4:0", "[::1]:0", "9.0.0.0:0"],
&["1.2.3.4:443", "[::1]:500", "9.0.0.0:80", "[::1]:80"],
);
check(
"*4:0",
&["1.2.3.4:0", "9.0.0.0:0"],
&["1.2.3.4:443", "9.0.0.0:80", "[::1]:0", "[::1]:80"],
);
check(
"*6:0",
&["[::1]:0"],
&["[::1]:80", "1.2.3.4:0", "1.2.3.4:443"],
);
}
#[test]
@@ -620,6 +637,7 @@ mod test {
policy.push(AddressPolicyAction::Accept, "*:443".parse()?);
policy.push(AddressPolicyAction::Accept, "[::1]:80".parse()?);
policy.push(AddressPolicyAction::Reject, "*:80".parse()?);
policy.push(AddressPolicyAction::Accept, "*:0".parse()?);
let policy = policy; // drop mut
assert!(policy
@@ -640,6 +658,9 @@ mod test {
assert!(policy
.allows_sockaddr(&"127.0.0.1:66".parse().unwrap())
.is_none());
assert!(policy
.allows_sockaddr(&"127.0.0.1:0".parse().unwrap())
.unwrap());
Ok(())
}
@@ -672,7 +693,6 @@ mod test {
assert_eq!("*".parse::<PortRange>().unwrap(), PortRange::new_all());
assert!("hello".parse::<PortRange>().is_err());
assert!("0".parse::<PortRange>().is_err());
assert!("65536".parse::<PortRange>().is_err());
assert!("65537".parse::<PortRange>().is_err());
assert!("1-2-3".parse::<PortRange>().is_err());
@@ -680,6 +700,9 @@ mod test {
assert!("1-".parse::<PortRange>().is_err());
assert!("-2".parse::<PortRange>().is_err());
assert!("-".parse::<PortRange>().is_err());
assert_eq!("0".parse::<PortRange>().unwrap(), PortRange::new_zero(),);
assert!("0-1".parse::<PortRange>().is_err());
}
#[test]
+2 -1
View File
@@ -2,6 +2,7 @@
name = "ledger"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -10,4 +11,4 @@ bip32 = "0.5.1"
k256 = { workspace = true }
ledger-transport = "0.10.0"
ledger-transport-hid = "0.10.0"
thiserror = { workspace = true }
thiserror = { workspace = true }
+2 -1
View File
@@ -3,6 +3,7 @@ name = "nym-mixnode-common"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -20,7 +21,7 @@ tokio = { version = "1.24.1", features = [
"net",
"io-util",
] }
tokio-util = { version = "0.7.4", features = ["codec"] }
tokio-util = { workspace = true, features = ["codec"] }
url = { workspace = true }
thiserror = { workspace = true }
+3 -3
View File
@@ -108,13 +108,13 @@ impl ConnectionHandler {
let reply_packet = match maybe_echo_packet {
Some(Ok(echo_packet)) => self.handle_echo_packet(echo_packet),
Some(Err(err)) => {
error!(
debug!(
"The socket connection got corrupted with error: {err}. Closing the socket",
);
return;
}
None => {
error!("The socket connection got terminated by the remote!");
debug!("The socket connection got terminated by the remote!");
return;
}
};
@@ -125,7 +125,7 @@ impl ConnectionHandler {
.write_all(reply_packet.to_bytes().as_ref())
.await
{
error!(
debug!(
"Failed to write reply packet back to the sender - {}. Closing the socket on our end",
err
);
+13 -1
View File
@@ -111,6 +111,7 @@ impl NymNetworkDetails {
.with_additional_validator_endpoint(ValidatorDetails::new(
var(var_names::NYXD).expect("nyxd validator not set"),
Some(var(var_names::NYM_API).expect("nym api not set")),
get_optional_env(var_names::NYXD_WEBSOCKET),
))
.with_mixnet_contract(Some(
var(var_names::MIXNET_CONTRACT_ADDRESS).expect("mixnet contract not set"),
@@ -340,6 +341,9 @@ impl DenomDetailsOwned {
pub struct ValidatorDetails {
// it is assumed those values are always valid since they're being provided in our defaults file
pub nyxd_url: String,
//
pub websocket_url: Option<String>,
// Right now api_url is optional as we are not running the api reliably on all validators
// however, later on it should be a mandatory field
pub api_url: Option<String>,
@@ -347,9 +351,10 @@ pub struct ValidatorDetails {
}
impl ValidatorDetails {
pub fn new<S: Into<String>>(nyxd_url: S, api_url: Option<S>) -> Self {
pub fn new<S: Into<String>>(nyxd_url: S, api_url: Option<S>, websocket_url: Option<S>) -> Self {
ValidatorDetails {
nyxd_url: nyxd_url.into(),
websocket_url: websocket_url.map(Into::into),
api_url: api_url.map(Into::into),
}
}
@@ -357,6 +362,7 @@ impl ValidatorDetails {
pub fn new_nyxd_only<S: Into<String>>(nyxd_url: S) -> Self {
ValidatorDetails {
nyxd_url: nyxd_url.into(),
websocket_url: None,
api_url: None,
}
}
@@ -372,6 +378,12 @@ impl ValidatorDetails {
.as_ref()
.map(|url| url.parse().expect("the provided api url is invalid!"))
}
pub fn websocket_url(&self) -> Option<Url> {
self.websocket_url
.as_ref()
.map(|url| url.parse().expect("the provided websocket url is invalid!"))
}
}
fn fix_deprecated_environmental_variables() {
+15 -1
View File
@@ -3,6 +3,7 @@
use crate::var_names;
use crate::{DenomDetails, ValidatorDetails};
use std::str::FromStr;
pub const NETWORK_NAME: &str = "mainnet";
@@ -25,6 +26,7 @@ pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/";
pub const NYXD_URL: &str = "https://rpc.nymtech.net";
pub const NYM_API: &str = "https://validator.nymtech.net/api/";
pub const NYXD_WS: &str = "wss://rpc.nymtech.net/websocket";
pub const EXPLORER_API: &str = "https://explorer.nymtech.net/api/";
// I'm making clippy mad on purpose, because that url HAS TO be updated and deployed before merging
@@ -32,7 +34,11 @@ pub const EXIT_POLICY_URL: &str =
"https://nymtech.net/.wellknown/network-requester/exit-policy.txt";
pub(crate) fn validators() -> Vec<ValidatorDetails> {
vec![ValidatorDetails::new(NYXD_URL, Some(NYM_API))]
vec![ValidatorDetails::new(
NYXD_URL,
Some(NYM_API),
Some(NYXD_WS),
)]
}
const DEFAULT_SUFFIX: &str = "_MAINNET_DEFAULT";
@@ -60,6 +66,12 @@ pub fn read_var_if_not_default(var: &str) -> Option<String> {
}
}
pub fn read_parsed_var_if_not_default<T: FromStr>(var: &str) -> Option<Result<T, T::Err>> {
read_var_if_not_default(var)
.as_deref()
.map(FromStr::from_str)
}
pub fn export_to_env() {
set_var_to_default(var_names::CONFIGURED, "true");
set_var_to_default(var_names::NETWORK_NAME, NETWORK_NAME);
@@ -104,6 +116,7 @@ pub fn export_to_env() {
);
set_var_to_default(var_names::NYXD, NYXD_URL);
set_var_to_default(var_names::NYM_API, NYM_API);
set_var_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS);
set_var_to_default(var_names::EXPLORER_API, EXPLORER_API);
set_var_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL);
}
@@ -152,6 +165,7 @@ pub fn export_to_env_if_not_set() {
);
set_var_conditionally_to_default(var_names::NYXD, NYXD_URL);
set_var_conditionally_to_default(var_names::NYM_API, NYM_API);
set_var_conditionally_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS);
set_var_conditionally_to_default(var_names::EXPLORER_API, EXPLORER_API);
set_var_conditionally_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL);
}
+1
View File
@@ -26,6 +26,7 @@ pub const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
pub const NAME_SERVICE_CONTRACT_ADDRESS: &str = "NAME_SERVICE_CONTRACT_ADDRESS";
pub const NYXD: &str = "NYXD";
pub const NYM_API: &str = "NYM_API";
pub const NYXD_WEBSOCKET: &str = "NYXD_WS";
pub const EXPLORER_API: &str = "EXPLORER_API";
pub const EXIT_POLICY_URL: &str = "EXIT_POLICY";
+1
View File
@@ -2,6 +2,7 @@
name = "nym-node-tester-utils"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -3,6 +3,7 @@ name = "nym-nonexhaustive-delayqueue"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+7 -3
View File
@@ -3,11 +3,12 @@ name = "nym-coconut"
version = "0.5.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>", "Ania Piotrowska <ania@nymtech.net>"]
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch ="gt-serialisation", default-features = false, features = ["pairings", "alloc", "experimental"] }
bls12_381 = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] }
itertools = "0.10"
digest = "0.9"
rand = "0.8"
@@ -16,16 +17,17 @@ serde = { workspace = true }
serde_derive = "1.0"
bs58 = "0.4.0"
sha2 = "0.9"
zeroize = { workspace = true, optional = true }
nym-dkg = { path = "../dkg" }
nym-pemstore = { path = "../pemstore" }
[dependencies.ff]
version = "0.11"
workspace = true
default-features = false
[dependencies.group]
version = "0.11"
workspace = true
default-features = false
[dev-dependencies]
@@ -38,7 +40,9 @@ name = "benchmarks"
harness = false
[features]
key-zeroize = ["zeroize", "bls12_381/zeroize"]
default = []
[target.'cfg(target_env = "wasm32-unknown-unknown")'.dependencies]
getrandom = { version="0.2", features=["js"] }
+14 -14
View File
@@ -7,7 +7,7 @@ use ff::Field;
use group::{Curve, Group};
use nym_coconut::{
aggregate_signature_shares, aggregate_verification_keys, blind_sign, prepare_blind_sign,
prove_bandwidth_credential, setup, ttp_keygen, verify_credential,
prove_bandwidth_credential, random_scalars_refs, setup, ttp_keygen, verify_credential,
verify_partial_blind_signature, Attribute, BlindedSignature, Parameters, Signature,
SignatureShare, VerificationKey,
};
@@ -66,8 +66,8 @@ fn unblind_and_aggregate(
params: &Parameters,
blinded_signatures: &[BlindedSignature],
partial_verification_keys: &[VerificationKey],
private_attributes: &[Attribute],
public_attributes: &[Attribute],
private_attributes: &[&Attribute],
public_attributes: &[&Attribute],
commitment_hash: &G1Projective,
pedersen_commitments_openings: &[Scalar],
verification_key: &VerificationKey,
@@ -78,7 +78,7 @@ fn unblind_and_aggregate(
.zip(partial_verification_keys.iter())
.map(|(signature, partial_verification_key)| {
signature
.unblind(
.unblind_and_verify(
params,
partial_verification_key,
private_attributes,
@@ -171,10 +171,10 @@ fn bench_coconut(c: &mut Criterion) {
let params = setup(case.num_public_attrs + case.num_private_attrs).unwrap();
let public_attributes = params.n_random_scalars(case.num_public_attrs as usize);
random_scalars_refs!(public_attributes, params, case.num_public_attrs as usize);
let serial_number = params.random_scalar();
let binding_number = params.random_scalar();
let private_attributes = vec![serial_number, binding_number];
let private_attributes = vec![&serial_number, &binding_number];
// The prepare blind sign is performed by the user
let (pedersen_commitments_openings, blind_sign_request) =
@@ -213,7 +213,7 @@ fn bench_coconut(c: &mut Criterion) {
b.iter(|| {
blind_sign(
&params,
&keypair.secret_key(),
keypair.secret_key(),
&blind_sign_request,
&public_attributes,
)
@@ -228,7 +228,7 @@ fn bench_coconut(c: &mut Criterion) {
for keypair in coconut_keypairs.iter() {
let blinded_signature = blind_sign(
&params,
&keypair.secret_key(),
keypair.secret_key(),
&blind_sign_request,
&public_attributes,
)
@@ -238,7 +238,7 @@ fn bench_coconut(c: &mut Criterion) {
let verification_keys: Vec<VerificationKey> = coconut_keypairs
.iter()
.map(|keypair| keypair.verification_key())
.map(|keypair| keypair.verification_key().clone())
.collect();
// verify a random partial blind signature
@@ -255,7 +255,7 @@ fn bench_coconut(c: &mut Criterion) {
b.iter(|| {
verify_partial_blind_signature(
&params,
&blind_sign_request,
blind_sign_request.get_private_attributes_pedersen_commitments(),
&public_attributes,
random_blind_signature,
partial_verification_key,
@@ -310,8 +310,8 @@ fn bench_coconut(c: &mut Criterion) {
&params,
&aggr_verification_key,
&aggregated_signature,
serial_number,
binding_number,
&serial_number,
&binding_number,
)
.unwrap();
@@ -329,8 +329,8 @@ fn bench_coconut(c: &mut Criterion) {
&params,
&aggr_verification_key,
&aggregated_signature,
serial_number,
binding_number,
&serial_number,
&binding_number,
)
.unwrap()
})
+34 -13
View File
@@ -34,7 +34,10 @@ impl TryFrom<&[u8]> for Ciphertext {
)));
}
// safety: we just checked for the length so the unwraps are fine
#[allow(clippy::unwrap_used)]
let c1_bytes: &[u8; 48] = &bytes[..48].try_into().unwrap();
#[allow(clippy::unwrap_used)]
let c2_bytes: &[u8; 48] = &bytes[48..].try_into().unwrap();
let c1 = try_deserialize_g1_projective(
@@ -112,7 +115,16 @@ impl Bytable for PrivateKey {
}
fn try_from_byte_slice(slice: &[u8]) -> Result<Self> {
PrivateKey::from_bytes(slice.try_into().unwrap())
let received = slice.len();
let Ok(arr) = slice.try_into() else {
return Err(CoconutError::UnexpectedArrayLength {
typ: "elgamal::PrivateKey".to_string(),
received,
expected: 32,
});
};
PrivateKey::from_bytes(arr)
}
}
@@ -145,21 +157,36 @@ impl PublicKey {
}
pub fn to_bytes(&self) -> [u8; 48] {
self.to_byte_vec().try_into().unwrap()
self.0.to_affine().to_compressed()
}
pub fn from_bytes(bytes: &[u8; 48]) -> Result<PublicKey> {
Ok(PublicKey::try_from(bytes.to_vec().as_slice()).unwrap())
try_deserialize_g1_projective(
bytes,
CoconutError::Deserialization(
"Failed to deserialize compressed ElGamal public key".to_string(),
),
)
.map(PublicKey)
}
}
impl Bytable for PublicKey {
fn to_byte_vec(&self) -> Vec<u8> {
self.0.to_affine().to_compressed().into()
self.to_bytes().into()
}
fn try_from_byte_slice(slice: &[u8]) -> Result<Self> {
Ok(PublicKey::from_bytes(slice.try_into().unwrap()).unwrap())
let received = slice.len();
let Ok(arr) = slice.try_into() else {
return Err(CoconutError::UnexpectedArrayLength {
typ: "elgamal::PublicKey".to_string(),
received,
expected: 48,
});
};
PublicKey::from_bytes(arr)
}
}
@@ -167,13 +194,7 @@ impl TryFrom<&[u8]> for PublicKey {
type Error = CoconutError;
fn try_from(slice: &[u8]) -> Result<PublicKey> {
try_deserialize_g1_projective(
slice.try_into().unwrap(),
CoconutError::Deserialization(
"Failed to deserialize compressed ElGamal public key".to_string(),
),
)
.map(PublicKey)
PublicKey::try_from_byte_slice(slice)
}
}
@@ -225,7 +246,7 @@ pub fn elgamal_keygen(params: &Parameters) -> ElGamalKeyPair {
pub fn compute_attribute_encryption(
params: &Parameters,
private_attributes: &[Attribute],
private_attributes: &[&Attribute],
pub_key: &PublicKey,
commitment_hash: G1Projective,
) -> (Vec<Ciphertext>, Vec<EphemeralKey>) {
+16
View File
@@ -50,4 +50,20 @@ pub enum CoconutError {
modulus: usize,
object: String,
},
#[error("received an array of unexpected size for deserialization of {typ}. got {received} but expected {expected}")]
UnexpectedArrayLength {
typ: String,
received: usize,
expected: usize,
},
#[error("failed to decode the base58 representation: {0}")]
Base58DecodingFailure(#[from] bs58::decode::Error),
#[error("failed to deserialize scalar from the received bytes - it might not have been canonically encoded")]
ScalarDeserializationFailure,
#[error("failed to deserialize G1Projective point from the received bytes - it might not have been canonically encoded")]
G1ProjectiveDeserializationFailure,
}
+5 -16
View File
@@ -1,11 +1,9 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::convert::TryInto;
#![warn(clippy::expect_used)]
#![warn(clippy::unwrap_used)]
use bls12_381::Scalar;
pub use crate::traits::Bytable;
pub use elgamal::elgamal_keygen;
pub use elgamal::ElGamalKeyPair;
pub use elgamal::PublicKey;
@@ -30,6 +28,7 @@ pub use scheme::BlindedSignature;
pub use scheme::Signature;
pub use scheme::SignatureShare;
pub use traits::Base58;
pub use traits::Bytable;
pub use utils::hash_to_scalar;
pub mod elgamal;
@@ -41,18 +40,8 @@ pub mod tests;
mod traits;
mod utils;
pub type Attribute = Scalar;
pub type Attribute = bls12_381::Scalar;
pub type PrivateAttribute = Attribute;
pub type PublicAttribute = Attribute;
impl Bytable for Attribute {
fn to_byte_vec(&self) -> Vec<u8> {
self.to_bytes().to_vec()
}
fn try_from_byte_slice(slice: &[u8]) -> Result<Self, CoconutError> {
Ok(Attribute::from_bytes(slice.try_into().unwrap()).unwrap())
}
}
impl Base58 for Attribute {}
pub use bls12_381::G1Projective;
+38 -26
View File
@@ -91,8 +91,8 @@ impl ProofCmCs {
commitment_opening: &Scalar,
commitments: &[G1Projective],
pedersen_commitments_openings: &[Scalar],
private_attributes: &[Attribute],
public_attributes: &[Attribute],
private_attributes: &[&Attribute],
public_attributes: &[&Attribute],
) -> Self {
// note: this is only called from `prepare_blind_sign` that already checks
// whether private attributes are non-empty and whether we don't have too many
@@ -162,11 +162,8 @@ impl ProofCmCs {
&challenge,
&pedersen_commitments_openings.iter().collect::<Vec<_>>(),
);
let response_attributes = produce_responses(
&witness_attributes,
&challenge,
&private_attributes.iter().collect::<Vec<_>>(),
);
let response_attributes =
produce_responses(&witness_attributes, &challenge, private_attributes);
ProofCmCs {
challenge,
@@ -181,7 +178,7 @@ impl ProofCmCs {
params: &Parameters,
commitment: &G1Projective,
commitments: &[G1Projective],
public_attributes: &[Attribute],
public_attributes: &[&Attribute],
) -> bool {
if self.response_attributes.len() != commitments.len() {
return false;
@@ -203,7 +200,7 @@ impl ProofCmCs {
- public_attributes
.iter()
.zip(params.gen_hs().iter().skip(self.response_attributes.len()))
.map(|(pub_attr, hs)| hs * pub_attr)
.map(|(&pub_attr, hs)| hs * pub_attr)
.sum::<G1Projective>())
* self.challenge
+ g1 * self.response_opening
@@ -280,8 +277,12 @@ impl ProofCmCs {
}
let mut idx = 0;
// safety: bound checked + constant offset
#[allow(clippy::unwrap_used)]
let challenge_bytes = bytes[idx..idx + 32].try_into().unwrap();
idx += 32;
// safety: bound checked + constant offset
#[allow(clippy::unwrap_used)]
let response_opening_bytes = bytes[idx..idx + 32].try_into().unwrap();
idx += 32;
@@ -297,6 +298,8 @@ impl ProofCmCs {
),
)?;
// safety: bound checked + constant offset
#[allow(clippy::unwrap_used)]
let ro_len = u64::from_le_bytes(bytes[idx..idx + 8].try_into().unwrap());
idx += 8;
if bytes[idx..].len() < ro_len as usize * 32 + 8 {
@@ -313,6 +316,8 @@ impl ProofCmCs {
CoconutError::Deserialization("Failed to deserialize openings response".to_string()),
)?;
// safety: bound checked + constant offset
#[allow(clippy::unwrap_used)]
let rm_len = u64::from_le_bytes(bytes[ro_end..ro_end + 8].try_into().unwrap());
let response_attributes = try_deserialize_scalar_vec(
rm_len,
@@ -462,7 +467,7 @@ impl ProofKappaZeta {
pub(crate) fn from_bytes(bytes: &[u8]) -> Result<Self> {
// at the very minimum there must be a single attribute being proven
if bytes.len() < 32 * 4 || (bytes.len()) % 32 != 0 {
if bytes.len() != 128 {
return Err(CoconutError::DeserializationInvalidLength {
actual: bytes.len(),
modulus_target: bytes.len(),
@@ -472,24 +477,32 @@ impl ProofKappaZeta {
});
}
// safety: bound checked + constant offset
#[allow(clippy::unwrap_used)]
let challenge_bytes = bytes[..32].try_into().unwrap();
let challenge = try_deserialize_scalar(
&challenge_bytes,
CoconutError::Deserialization("Failed to deserialize challenge".to_string()),
)?;
// safety: bound checked + constant offset
#[allow(clippy::unwrap_used)]
let serial_number_bytes = &bytes[32..64].try_into().unwrap();
let response_serial_number = try_deserialize_scalar(
serial_number_bytes,
CoconutError::Deserialization("failed to deserialize the serial number".to_string()),
)?;
// safety: bound checked + constant offset
#[allow(clippy::unwrap_used)]
let binding_number_bytes = &bytes[64..96].try_into().unwrap();
let response_binding_number = try_deserialize_scalar(
binding_number_bytes,
CoconutError::Deserialization("failed to deserialize the binding number".to_string()),
)?;
// safety: bound checked + constant offset
#[allow(clippy::unwrap_used)]
let blinder_bytes = bytes[96..].try_into().unwrap();
let response_blinder = try_deserialize_scalar(
&blinder_bytes,
@@ -512,14 +525,13 @@ impl ProofKappaZeta {
#[cfg(test)]
mod tests {
use group::Group;
use rand::thread_rng;
use super::*;
use crate::scheme::keygen::keygen;
use crate::scheme::setup::setup;
use crate::scheme::verification::{compute_kappa, compute_zeta};
use super::*;
use crate::tests::helpers::random_scalars_refs;
use group::Group;
use rand::thread_rng;
#[test]
fn proof_cm_cs_bytes_roundtrip() {
@@ -530,7 +542,7 @@ mod tests {
let r = params.random_scalar();
let cms: [G1Projective; 1] = [G1Projective::random(&mut rng)];
let rs = params.n_random_scalars(1);
let private_attributes = params.n_random_scalars(1);
random_scalars_refs!(private_attributes, params, 1);
// 0 public 1 private
let pi_s = ProofCmCs::construct(&params, &cm, &r, &cms, &rs, &private_attributes, &[]);
@@ -546,7 +558,7 @@ mod tests {
G1Projective::random(&mut rng),
];
let rs = params.n_random_scalars(2);
let private_attributes = params.n_random_scalars(2);
random_scalars_refs!(private_attributes, params, 2);
// 0 public 2 privates
let pi_s = ProofCmCs::construct(&params, &cm, &r, &cms, &rs, &private_attributes, &[]);
@@ -562,20 +574,20 @@ mod tests {
let keypair = keygen(&params);
// we don't care about 'correctness' of the proof. only whether we can correctly recover it from bytes
let serial_number = params.random_scalar();
let binding_number = params.random_scalar();
let serial_number = &params.random_scalar();
let binding_number = &params.random_scalar();
let private_attributes = vec![serial_number, binding_number];
let r = params.random_scalar();
let kappa = compute_kappa(&params, &keypair.verification_key(), &private_attributes, r);
let kappa = compute_kappa(&params, keypair.verification_key(), &private_attributes, r);
let zeta = compute_zeta(&params, serial_number);
// 0 public 2 private
let pi_v = ProofKappaZeta::construct(
&params,
&keypair.verification_key(),
&serial_number,
&binding_number,
keypair.verification_key(),
serial_number,
binding_number,
&r,
&kappa,
&zeta,
@@ -592,9 +604,9 @@ mod tests {
let pi_v = ProofKappaZeta::construct(
&params,
&keypair.verification_key(),
&serial_number,
&binding_number,
keypair.verification_key(),
serial_number,
binding_number,
&r,
&kappa,
&zeta,
+35 -15
View File
@@ -83,7 +83,7 @@ pub fn aggregate_verification_keys(
pub fn aggregate_signatures(
params: &Parameters,
verification_key: &VerificationKey,
attributes: &[Attribute],
attributes: &[&Attribute],
signatures: &[PartialSignature],
indices: Option<&[SignerIndex]>,
) -> Result<Signature> {
@@ -100,7 +100,7 @@ pub fn aggregate_signatures(
let tmp = attributes
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(attr, beta_i)| beta_i * attr)
.map(|(&attr, beta_i)| beta_i * attr)
.sum::<G2Projective>();
if !check_bilinear_pairing(
@@ -119,7 +119,7 @@ pub fn aggregate_signatures(
pub fn aggregate_signature_shares(
params: &Parameters,
verification_key: &VerificationKey,
attributes: &[Attribute],
attributes: &[&Attribute],
shares: &[SignatureShare],
) -> Result<Signature> {
let (signatures, indices): (Vec<_>, Vec<_>) = shares
@@ -138,13 +138,13 @@ pub fn aggregate_signature_shares(
#[cfg(test)]
mod tests {
use bls12_381::G1Projective;
use group::Group;
use crate::scheme::issuance::sign;
use crate::scheme::keygen::ttp_keygen;
use crate::scheme::setup::Parameters;
use crate::scheme::verification::verify;
use crate::tests::helpers::random_scalars_refs;
use bls12_381::G1Projective;
use group::Group;
use super::*;
@@ -155,7 +155,7 @@ mod tests {
let vks = keypairs
.into_iter()
.map(|keypair| keypair.verification_key())
.map(|keypair| keypair.verification_key().clone())
.collect::<Vec<_>>();
let aggr_vk1 = aggregate_verification_keys(&vks[..3], Some(&[1, 2, 3])).unwrap();
@@ -212,13 +212,18 @@ mod tests {
#[test]
fn signature_aggregation_works_for_any_subset_of_signatures() {
let mut params = Parameters::new(2).unwrap();
let attributes = params.n_random_scalars(2);
random_scalars_refs!(attributes, params, 2);
let keypairs = ttp_keygen(&params, 3, 5).unwrap();
let (sks, vks): (Vec<_>, Vec<_>) = keypairs
.into_iter()
.map(|keypair| (keypair.secret_key(), keypair.verification_key()))
.map(|keypair| {
(
keypair.secret_key().clone(),
keypair.verification_key().clone(),
)
})
.unzip();
let sigs = sks
@@ -312,12 +317,17 @@ mod tests {
fn signature_aggregation_doesnt_work_for_empty_set_of_signatures() {
let signatures: Vec<Signature> = vec![];
let params = Parameters::new(2).unwrap();
let attributes = params.n_random_scalars(2);
random_scalars_refs!(attributes, params, 2);
let keypairs = ttp_keygen(&params, 3, 5).unwrap();
let (_, vks): (Vec<_>, Vec<_>) = keypairs
.into_iter()
.map(|keypair| (keypair.secret_key(), keypair.verification_key()))
.map(|keypair| {
(
keypair.secret_key().clone(),
keypair.verification_key().clone(),
)
})
.unzip();
let aggr_vk_all = aggregate_verification_keys(&vks, None).unwrap();
@@ -330,11 +340,16 @@ mod tests {
fn signature_aggregation_doesnt_work_if_indices_have_invalid_length() {
let signatures = vec![random_signature()];
let params = Parameters::new(2).unwrap();
let attributes = params.n_random_scalars(2);
random_scalars_refs!(attributes, params, 2);
let keypairs = ttp_keygen(&params, 3, 5).unwrap();
let (_, vks): (Vec<_>, Vec<_>) = keypairs
.into_iter()
.map(|keypair| (keypair.secret_key(), keypair.verification_key()))
.map(|keypair| {
(
keypair.secret_key().clone(),
keypair.verification_key().clone(),
)
})
.unzip();
let aggr_vk_all = aggregate_verification_keys(&vks, None).unwrap();
@@ -356,11 +371,16 @@ mod tests {
fn signature_aggregation_doesnt_work_for_non_unique_indices() {
let signatures = vec![random_signature(), random_signature()];
let params = Parameters::new(2).unwrap();
let attributes = params.n_random_scalars(2);
random_scalars_refs!(attributes, params, 2);
let keypairs = ttp_keygen(&params, 3, 5).unwrap();
let (_, vks): (Vec<_>, Vec<_>) = keypairs
.into_iter()
.map(|keypair| (keypair.secret_key(), keypair.verification_key()))
.map(|keypair| {
(
keypair.secret_key().clone(),
keypair.verification_key().clone(),
)
})
.unzip();
let aggr_vk_all = aggregate_verification_keys(&vks, None).unwrap();
@@ -25,6 +25,8 @@ impl TryFrom<&[u8]> for BlindedSerialNumber {
));
}
// safety: we've just made a check for 96 bytes
#[allow(clippy::unwrap_used)]
let inner = try_deserialize_g2_projective(
&bytes.try_into().unwrap(),
CoconutError::Deserialization(
+58 -41
View File
@@ -54,6 +54,8 @@ impl TryFrom<&[u8]> for BlindSignRequest {
let commitment_bytes_len = 48;
let commitment_hash_bytes_len = 48;
// safety: we made bound check and we're using constant offest
#[allow(clippy::unwrap_used)]
let cm_bytes = bytes[..j + commitment_bytes_len].try_into().unwrap();
let commitment = try_deserialize_g1_projective(
&cm_bytes,
@@ -63,6 +65,8 @@ impl TryFrom<&[u8]> for BlindSignRequest {
)?;
j += commitment_bytes_len;
// safety: we made bound check and we're using constant offest
#[allow(clippy::unwrap_used)]
let cm_hash_bytes = bytes[j..j + commitment_hash_bytes_len].try_into().unwrap();
let commitment_hash = try_deserialize_g1_projective(
&cm_hash_bytes,
@@ -72,6 +76,8 @@ impl TryFrom<&[u8]> for BlindSignRequest {
)?;
j += commitment_hash_bytes_len;
// safety: we made bound check and we're using constant offest
#[allow(clippy::unwrap_used)]
let c_len = u64::from_le_bytes(bytes[j..j + 8].try_into().unwrap());
j += 8;
if bytes[j..].len() < c_len as usize * 48 {
@@ -86,6 +92,14 @@ impl TryFrom<&[u8]> for BlindSignRequest {
let start = j + i * 48;
let end = start + 48;
if bytes.len() < end {
return Err(CoconutError::Deserialization(
"Failed to deserialize compressed commitment".to_string(),
));
}
// safety: we made bound check and we're using constant offest
#[allow(clippy::unwrap_used)]
let private_attributes_commitment_bytes = bytes[start..end].try_into().unwrap();
let private_attributes_commitment = try_deserialize_g1_projective(
&private_attributes_commitment_bytes,
@@ -137,7 +151,7 @@ impl Bytable for BlindSignRequest {
impl Base58 for BlindSignRequest {}
impl BlindSignRequest {
fn verify_proof(&self, params: &Parameters, public_attributes: &[Attribute]) -> bool {
fn verify_proof(&self, params: &Parameters, public_attributes: &[&Attribute]) -> bool {
self.pi_s.verify(
params,
&self.commitment,
@@ -150,8 +164,8 @@ impl BlindSignRequest {
self.commitment_hash
}
pub fn get_private_attributes_pedersen_commitments(&self) -> Vec<G1Projective> {
self.private_attributes_commitments.clone()
pub fn get_private_attributes_pedersen_commitments(&self) -> &[G1Projective] {
&self.private_attributes_commitments
}
pub fn to_bytes(&self) -> Vec<u8> {
@@ -161,12 +175,16 @@ impl BlindSignRequest {
pub fn from_bytes(bytes: &[u8]) -> Result<BlindSignRequest> {
BlindSignRequest::try_from(bytes)
}
pub fn num_private_attributes(&self) -> usize {
self.private_attributes_commitments.len()
}
}
pub fn compute_attributes_commitment(
params: &Parameters,
private_attributes: &[Attribute],
public_attributes: &[Attribute],
private_attributes: &[&Attribute],
public_attributes: &[&Attribute],
hs: &[G1Affine],
) -> (Scalar, G1Projective) {
let commitment_opening = params.random_scalar();
@@ -187,7 +205,7 @@ pub fn compute_attributes_commitment(
pub fn compute_pedersen_commitments_for_private_attributes(
params: &Parameters,
private_attributes: &[Attribute],
private_attributes: &[&Attribute],
h: &G1Projective,
) -> (Vec<Scalar>, Vec<G1Projective>) {
// Generate openings for Pedersen commitment for each private attribute
@@ -197,13 +215,13 @@ pub fn compute_pedersen_commitments_for_private_attributes(
let pedersen_commitments = commitments_openings
.iter()
.zip(private_attributes.iter())
.map(|(o_j, m_j)| params.gen1() * o_j + h * m_j)
.map(|(o_j, &m_j)| params.gen1() * o_j + h * m_j)
.collect::<Vec<_>>();
(commitments_openings, pedersen_commitments)
}
pub fn compute_hash(commitment: G1Projective, public_attributes: &[Attribute]) -> G1Projective {
pub fn compute_hash(commitment: G1Projective, public_attributes: &[&Attribute]) -> G1Projective {
let mut buff = Vec::new();
buff.extend_from_slice(commitment.to_bytes().as_ref());
for attr in public_attributes {
@@ -215,8 +233,8 @@ pub fn compute_hash(commitment: G1Projective, public_attributes: &[Attribute]) -
/// Builds cryptographic material required for blind sign.
pub fn prepare_blind_sign(
params: &Parameters,
private_attributes: &[Attribute],
public_attributes: &[Attribute],
private_attributes: &[&Attribute],
public_attributes: &[&Attribute],
) -> Result<(Vec<Scalar>, BlindSignRequest)> {
if private_attributes.is_empty() {
return Err(CoconutError::Issuance(
@@ -271,7 +289,7 @@ pub fn blind_sign(
params: &Parameters,
signing_secret_key: &SecretKey,
blind_sign_request: &BlindSignRequest,
public_attributes: &[Attribute],
public_attributes: &[&Attribute],
) -> Result<BlindedSignature> {
let num_private = blind_sign_request.private_attributes_commitments.len();
let hs = params.gen_hs();
@@ -304,7 +322,7 @@ pub fn blind_sign(
let signed_public = h * public_attributes
.iter()
.zip(signing_secret_key.ys.iter().skip(num_private))
.map(|(attr, yi)| attr * yi)
.map(|(&attr, yi)| attr * yi)
.sum::<Scalar>();
// h ^ x + c[0] ^ y[0] + ... c[m] ^ y[m] + h ^ (pub_m[0] * y[m + 1] + ... + pub_m[n] * y[m + n])
@@ -344,12 +362,12 @@ pub fn blind_sign(
/// The function returns `true` if the partial blind signature is valid, and `false` otherwise.
pub fn verify_partial_blind_signature(
params: &Parameters,
blind_sign_request: &BlindSignRequest,
public_attributes: &[Attribute],
private_attribute_commitments: &[G1Projective],
public_attributes: &[&Attribute],
blind_sig: &BlindedSignature,
partial_verification_key: &VerificationKey,
) -> bool {
let num_private_attributes = blind_sign_request.private_attributes_commitments.len();
let num_private_attributes = private_attribute_commitments.len();
if num_private_attributes + public_attributes.len() > partial_verification_key.beta_g2.len() {
return false;
}
@@ -370,8 +388,7 @@ pub fn verify_partial_blind_signature(
];
// for each private attribute, add (cm_i, beta_i) to the miller terms
for (private_attr_commit, beta_g2) in blind_sign_request
.private_attributes_commitments
for (private_attr_commit, beta_g2) in private_attribute_commitments
.iter()
.zip(&partial_verification_key.beta_g2)
{
@@ -383,7 +400,7 @@ pub fn verify_partial_blind_signature(
}
// for each public attribute, add (s^pub_j, beta_{priv + j}) to the miller terms
for (pub_attr, beta_g2) in public_attributes.iter().zip(
for (&pub_attr, beta_g2) in public_attributes.iter().zip(
partial_verification_key
.beta_g2
.iter()
@@ -404,7 +421,7 @@ pub fn verify_partial_blind_signature(
// is equivalent to checking e(a, b) • e(c, d)^{-1} == id
// and thus to e(a, b) • e(c^{-1}, d) == id
//
// compute e(c^1, g2) • e(s, alpha) • e(cm_0, beta_0) • e(cm_i, beta_i) • (s^pub_0, beta_{i+1}) (s^pub_j, beta_{i + j})
// compute e(c^{-1}, g2) • e(s, alpha) • e(cm_0, beta_0) • e(cm_i, beta_i) • (s^pub_0, beta_{i+1}) (s^pub_j, beta_{i + j})
multi_miller_loop(&terms_refs)
.final_exponentiation()
.is_identity()
@@ -415,7 +432,7 @@ pub fn verify_partial_blind_signature(
pub fn sign(
params: &mut Parameters,
secret_key: &SecretKey,
public_attributes: &[Attribute],
public_attributes: &[&Attribute],
) -> Result<Signature> {
if public_attributes.len() > secret_key.ys.len() {
return Err(CoconutError::IssuanceMaxAttributes {
@@ -429,7 +446,7 @@ pub fn sign(
// (the python implementation hashes string representation of all attributes onto the curve,
// but I think the same can be achieved by just summing the attributes thus avoiding the unnecessary
// transformation. If I'm wrong, please correct me.)
let attributes_sum = public_attributes.iter().sum::<Scalar>();
let attributes_sum = public_attributes.iter().copied().sum::<Scalar>();
let h = hash_g1((params.gen1() * attributes_sum).to_bytes());
// x + m0 * y0 + m1 * y1 + ... mn * yn
@@ -437,7 +454,7 @@ pub fn sign(
+ public_attributes
.iter()
.zip(secret_key.ys.iter())
.map(|(m_i, y_i)| m_i * y_i)
.map(|(&m_i, y_i)| m_i * y_i)
.sum::<Scalar>();
let sig2 = h * exponent;
@@ -448,13 +465,14 @@ pub fn sign(
mod tests {
use super::*;
use crate::scheme::keygen::keygen;
use crate::tests::helpers::random_scalars_refs;
#[test]
fn blind_sign_request_bytes_roundtrip() {
// 0 public and 1 private attribute
let params = Parameters::new(1).unwrap();
let private_attributes = params.n_random_scalars(1);
let public_attributes = params.n_random_scalars(0);
random_scalars_refs!(private_attributes, params, 1);
random_scalars_refs!(public_attributes, params, 0);
let (_commitments_openings, lambda) =
prepare_blind_sign(&params, &private_attributes, &public_attributes).unwrap();
@@ -467,8 +485,8 @@ mod tests {
// 2 public and 2 private attributes
let params = Parameters::new(4).unwrap();
let private_attributes = params.n_random_scalars(2);
let public_attributes = params.n_random_scalars(2);
random_scalars_refs!(private_attributes, params, 2);
random_scalars_refs!(public_attributes, params, 2);
let (_commitments_openings, lambda) =
prepare_blind_sign(&params, &private_attributes, &public_attributes).unwrap();
@@ -483,8 +501,8 @@ mod tests {
#[test]
fn successful_verify_partial_blind_signature() {
let params = Parameters::new(4).unwrap();
let private_attributes = params.n_random_scalars(2);
let public_attributes = params.n_random_scalars(2);
random_scalars_refs!(private_attributes, params, 2);
random_scalars_refs!(public_attributes, params, 2);
let (_commitments_openings, request) =
prepare_blind_sign(&params, &private_attributes, &public_attributes).unwrap();
@@ -492,7 +510,7 @@ mod tests {
let validator_keypair = keygen(&params);
let blind_sig = blind_sign(
&params,
&validator_keypair.secret_key(),
validator_keypair.secret_key(),
&request,
&public_attributes,
)
@@ -500,39 +518,38 @@ mod tests {
assert!(verify_partial_blind_signature(
&params,
&request,
&request.private_attributes_commitments,
&public_attributes,
&blind_sig,
&validator_keypair.verification_key()
validator_keypair.verification_key()
));
}
#[test]
fn successful_verify_partial_blind_signature_no_public_attributes() {
let params = Parameters::new(4).unwrap();
let private_attributes = params.n_random_scalars(2);
random_scalars_refs!(private_attributes, params, 2);
let (_commitments_openings, request) =
prepare_blind_sign(&params, &private_attributes, &[]).unwrap();
let validator_keypair = keygen(&params);
let blind_sig =
blind_sign(&params, &validator_keypair.secret_key(), &request, &[]).unwrap();
let blind_sig = blind_sign(&params, validator_keypair.secret_key(), &request, &[]).unwrap();
assert!(verify_partial_blind_signature(
&params,
&request,
&request.private_attributes_commitments,
&[],
&blind_sig,
&validator_keypair.verification_key()
validator_keypair.verification_key()
));
}
#[test]
fn fail_verify_partial_blind_signature_with_wrong_key() {
let params = Parameters::new(4).unwrap();
let private_attributes = params.n_random_scalars(2);
let public_attributes = params.n_random_scalars(2);
random_scalars_refs!(private_attributes, params, 2);
random_scalars_refs!(public_attributes, params, 2);
let (_commitments_openings, request) =
prepare_blind_sign(&params, &private_attributes, &public_attributes).unwrap();
@@ -541,7 +558,7 @@ mod tests {
let validator2_keypair = keygen(&params);
let blind_sig = blind_sign(
&params,
&validator_keypair.secret_key(),
validator_keypair.secret_key(),
&request,
&public_attributes,
)
@@ -550,10 +567,10 @@ mod tests {
// this assertion should fail, as we try to verify with a wrong validator key
assert!(!verify_partial_blind_signature(
&params,
&request,
&request.private_attributes_commitments,
&public_attributes,
&blind_sig,
&validator2_keypair.verification_key()
validator2_keypair.verification_key()
),);
}
}
+36 -7
View File
@@ -23,8 +23,12 @@ use crate::utils::{
};
use crate::Base58;
#[derive(Debug, Clone)]
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq, Eq, Clone))]
#[cfg_attr(
feature = "key-zeroize",
derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop)
)]
pub struct SecretKey {
pub(crate) x: Scalar,
pub(crate) ys: Vec<Scalar>,
@@ -62,7 +66,9 @@ impl TryFrom<&[u8]> for SecretKey {
}
// this conversion will not fail as we are taking the same length of data
#[allow(clippy::unwrap_used)]
let x_bytes: [u8; 32] = bytes[..32].try_into().unwrap();
#[allow(clippy::unwrap_used)]
let ys_len = u64::from_le_bytes(bytes[32..40].try_into().unwrap());
let actual_ys_len = (bytes.len() - 40) / 32;
@@ -97,6 +103,10 @@ impl SecretKey {
(self.x, self.ys.clone())
}
pub fn size(&self) -> usize {
self.ys.len()
}
/// Derive verification key using this secret key.
pub fn verification_key(&self, params: &Parameters) -> VerificationKey {
let g1 = params.gen1();
@@ -141,6 +151,10 @@ impl Base58 for SecretKey {}
// TODO: perhaps change points to affine representation
// to make verification slightly more efficient?
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(
feature = "key-zeroize",
derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop)
)]
pub struct VerificationKey {
// TODO add gen2 as per the paper or imply it from the fact library is using bls381?
pub(crate) alpha: G2Projective,
@@ -180,7 +194,9 @@ impl TryFrom<&[u8]> for VerificationKey {
}
// this conversion will not fail as we are taking the same length of data
#[allow(clippy::unwrap_used)]
let alpha_bytes: [u8; 96] = bytes[..96].try_into().unwrap();
#[allow(clippy::unwrap_used)]
let betas_len = u64::from_le_bytes(bytes[96..104].try_into().unwrap());
let actual_betas_len = (bytes.len() - 104) / (96 + 48);
@@ -204,6 +220,8 @@ impl TryFrom<&[u8]> for VerificationKey {
for i in 0..betas_len {
let start = (104 + i * 48) as usize;
let end = start + 48;
// we're using a constant 48 byte offset (which is the size of G1 compressed) so unwrap is fine
#[allow(clippy::unwrap_used)]
let beta_i_bytes = bytes[start..end].try_into().unwrap();
let beta_i = try_deserialize_g1_projective(
&beta_i_bytes,
@@ -220,6 +238,8 @@ impl TryFrom<&[u8]> for VerificationKey {
for i in 0..betas_len {
let start = (beta_g1_end + i * 96) as usize;
let end = start + 96;
// we're using a constant 96 byte offset (which is the size of G2 compressed) so unwrap is fine
#[allow(clippy::unwrap_used)]
let beta_i_bytes = bytes[start..end].try_into().unwrap();
let beta_i = try_deserialize_g2_projective(
&beta_i_bytes,
@@ -392,7 +412,11 @@ impl Bytable for VerificationKey {
impl Base58 for VerificationKey {}
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(test, derive(PartialEq, Eq))]
#[cfg_attr(test, derive(PartialEq, Eq, Clone))]
#[cfg_attr(
feature = "key-zeroize",
derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop)
)]
pub struct KeyPair {
secret_key: SecretKey,
verification_key: VerificationKey,
@@ -429,12 +453,12 @@ impl KeyPair {
}
}
pub fn secret_key(&self) -> SecretKey {
self.secret_key.clone()
pub fn secret_key(&self) -> &SecretKey {
&self.secret_key
}
pub fn verification_key(&self) -> VerificationKey {
self.verification_key.clone()
pub fn verification_key(&self) -> &VerificationKey {
&self.verification_key
}
pub fn to_bytes(&self) -> Vec<u8> {
@@ -488,6 +512,8 @@ impl TryFrom<&[u8]> for KeyPair {
});
}
// safety: we made bound check and we're using constant offest
#[allow(clippy::unwrap_used)]
let secret_key_len =
u64::from_le_bytes(bytes[header_len..header_len + 8].try_into().unwrap()) as usize;
let secret_key_start = header_len + 8;
@@ -503,6 +529,8 @@ impl TryFrom<&[u8]> for KeyPair {
});
}
// safety: we made bound check
#[allow(clippy::unwrap_used)]
let verification_key_len = u64::from_le_bytes(
bytes[secret_key_start + secret_key_len..secret_key_start + secret_key_len + 8]
.try_into()
@@ -515,6 +543,7 @@ impl TryFrom<&[u8]> for KeyPair {
)?;
let consumed_bytes = verification_key_start + verification_key_len;
let index = if consumed_bytes < bytes.len() && [consumed_bytes..].len() == 8 {
#[allow(clippy::unwrap_used)]
Some(u64::from_le_bytes(
bytes[consumed_bytes..consumed_bytes + 8]
.try_into()
+143 -97
View File
@@ -44,7 +44,10 @@ impl TryFrom<&[u8]> for Signature {
)));
}
// safety: we just checked for the length so the unwraps are fine
#[allow(clippy::expect_used)]
let sig1_bytes: &[u8; 48] = &bytes[..48].try_into().expect("Slice size != 48");
#[allow(clippy::expect_used)]
let sig2_bytes: &[u8; 48] = &bytes[48..].try_into().expect("Slice size != 48");
let sig1 = try_deserialize_g1_projective(
@@ -88,6 +91,45 @@ impl Signature {
pub fn from_bytes(bytes: &[u8]) -> Result<Signature> {
Signature::try_from(bytes)
}
pub fn verify(
&self,
params: &Parameters,
partial_verification_key: &VerificationKey,
private_attributes: &[&Attribute],
public_attributes: &[&Attribute],
commitment_hash: &G1Projective,
) -> Result<()> {
// Verify the commitment hash
if !(commitment_hash == &self.0) {
return Err(CoconutError::Verification(
"Verification of commitment hash from signature failed".to_string(),
));
}
let alpha = partial_verification_key.alpha;
let signed_attributes = private_attributes
.iter()
.chain(public_attributes.iter())
.zip(partial_verification_key.beta_g2.iter())
.map(|(&attr, beta_i)| beta_i * attr)
.sum::<G2Projective>();
// Verify the signature share
if !check_bilinear_pairing(
&self.0.to_affine(),
&G2Prepared::from((alpha + signed_attributes).to_affine()),
&self.1.to_affine(),
params.prepared_miller_g2(),
) {
return Err(CoconutError::Unblind(
"Verification of signature share failed".to_string(),
));
}
Ok(())
}
}
impl Bytable for Signature {
@@ -102,8 +144,7 @@ impl Bytable for Signature {
impl Base58 for Signature {}
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Debug, PartialEq, Eq)]
pub struct BlindedSignature(G1Projective, G1Projective);
impl Bytable for BlindedSignature {
@@ -129,7 +170,10 @@ impl TryFrom<&[u8]> for BlindedSignature {
)));
}
// safety: we just checked for the length so the unwraps are fine
#[allow(clippy::expect_used)]
let h_bytes: &[u8; 48] = &bytes[..48].try_into().expect("Slice size != 48");
#[allow(clippy::expect_used)]
let sig_bytes: &[u8; 48] = &bytes[48..].try_into().expect("Slice size != 48");
let h = try_deserialize_g1_projective(
@@ -148,24 +192,12 @@ impl TryFrom<&[u8]> for BlindedSignature {
impl BlindedSignature {
pub fn unblind(
&self,
params: &Parameters,
partial_verification_key: &VerificationKey,
private_attributes: &[Attribute],
public_attributes: &[Attribute],
commitment_hash: &G1Projective,
pedersen_commitments_openings: &[Scalar],
) -> Result<Signature> {
// parse the signature
let h = &self.0;
let c = &self.1;
// Verify the commitment hash
if !(commitment_hash == h) {
return Err(CoconutError::Unblind(
"Verification of commitment hash from signature failed".to_string(),
));
}
let blinding_removers = partial_verification_key
.beta_g1
.iter()
@@ -175,30 +207,29 @@ impl BlindedSignature {
let unblinded_c = c - blinding_removers;
let alpha = partial_verification_key.alpha;
let signed_attributes = private_attributes
.iter()
.chain(public_attributes.iter())
.zip(partial_verification_key.beta_g2.iter())
.map(|(attr, beta_i)| beta_i * attr)
.sum::<G2Projective>();
// Verify the signature share
if !check_bilinear_pairing(
&h.to_affine(),
&G2Prepared::from((alpha + signed_attributes).to_affine()),
&unblinded_c.to_affine(),
params.prepared_miller_g2(),
) {
return Err(CoconutError::Unblind(
"Verification of signature share failed".to_string(),
));
}
Ok(Signature(*h, unblinded_c))
}
pub fn unblind_and_verify(
&self,
params: &Parameters,
partial_verification_key: &VerificationKey,
private_attributes: &[&Attribute],
public_attributes: &[&Attribute],
commitment_hash: &G1Projective,
pedersen_commitments_openings: &[Scalar],
) -> Result<Signature> {
let unblinded = self.unblind(partial_verification_key, pedersen_commitments_openings)?;
unblinded.verify(
params,
partial_verification_key,
private_attributes,
public_attributes,
commitment_hash,
)?;
Ok(unblinded)
}
pub fn to_bytes(&self) -> [u8; 96] {
let mut bytes = [0u8; 96];
bytes[..48].copy_from_slice(&self.0.to_affine().to_compressed());
@@ -237,25 +268,25 @@ impl SignatureShare {
#[cfg(test)]
mod tests {
use super::*;
use crate::hash_to_scalar;
use crate::scheme::aggregation::{aggregate_signatures, aggregate_verification_keys};
use crate::scheme::issuance::{blind_sign, compute_hash, prepare_blind_sign, sign};
use crate::scheme::keygen::{keygen, ttp_keygen};
use crate::scheme::verification::{prove_bandwidth_credential, verify, verify_credential};
use super::*;
use crate::tests::helpers::random_scalars_refs;
#[test]
fn unblind_returns_error_if_integrity_check_on_commitment_hash_fails() {
let params = Parameters::new(2).unwrap();
let private_attributes = params.n_random_scalars(2_usize);
random_scalars_refs!(private_attributes, params, 2);
let (_commitments_openings, lambda) =
prepare_blind_sign(&params, &private_attributes, &[]).unwrap();
let keypair1 = keygen(&params);
let sig1 = blind_sign(&params, &keypair1.secret_key(), &lambda, &[]).unwrap();
let sig1 = blind_sign(&params, keypair1.secret_key(), &lambda, &[]).unwrap();
let wrong_commitment_opening = params.random_scalar();
let wrong_commitment = params.gen1() * wrong_commitment_opening;
@@ -263,9 +294,9 @@ mod tests {
let wrong_commitments_openings = params.n_random_scalars(private_attributes.len());
assert!(sig1
.unblind(
.unblind_and_verify(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&private_attributes,
&[],
&fake_commitment_hash,
@@ -277,20 +308,23 @@ mod tests {
#[test]
fn unblind_returns_error_if_signature_verification_fails() {
let params = Parameters::new(2).unwrap();
let private_attributes = vec![hash_to_scalar("Attribute1"), hash_to_scalar("Attribute2")];
let private_attributes2 = vec![hash_to_scalar("Attribute3"), hash_to_scalar("Attribute4")];
let p = [hash_to_scalar("Attribute1"), hash_to_scalar("Attribute2")];
let private_attributes = vec![&p[0], &p[1]];
let p2 = [hash_to_scalar("Attribute3"), hash_to_scalar("Attribute4")];
let private_attributes2 = vec![&p2[0], &p2[1]];
let (commitments_openings, lambda) =
prepare_blind_sign(&params, &private_attributes, &[]).unwrap();
let keypair1 = keygen(&params);
let sig1 = blind_sign(&params, &keypair1.secret_key(), &lambda, &[]).unwrap();
let sig1 = blind_sign(&params, keypair1.secret_key(), &lambda, &[]).unwrap();
assert!(sig1
.unblind(
.unblind_and_verify(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&private_attributes2,
&[],
&lambda.get_commitment_hash(),
@@ -304,7 +338,7 @@ mod tests {
let params = Parameters::new(2).unwrap();
let serial_number = params.random_scalar();
let binding_number = params.random_scalar();
let private_attributes = vec![serial_number, binding_number];
let private_attributes = vec![&serial_number, &binding_number];
let keypair1 = keygen(&params);
let keypair2 = keygen(&params);
@@ -312,11 +346,11 @@ mod tests {
let (commitments_openings, lambda) =
prepare_blind_sign(&params, &private_attributes, &[]).unwrap();
let sig1 = blind_sign(&params, &keypair1.secret_key(), &lambda, &[])
let sig1 = blind_sign(&params, keypair1.secret_key(), &lambda, &[])
.unwrap()
.unblind(
.unblind_and_verify(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&private_attributes,
&[],
&lambda.get_commitment_hash(),
@@ -324,11 +358,11 @@ mod tests {
)
.unwrap();
let sig2 = blind_sign(&params, &keypair2.secret_key(), &lambda, &[])
let sig2 = blind_sign(&params, keypair2.secret_key(), &lambda, &[])
.unwrap()
.unblind(
.unblind_and_verify(
&params,
&keypair2.verification_key(),
keypair2.verification_key(),
&private_attributes,
&[],
&lambda.get_commitment_hash(),
@@ -338,39 +372,39 @@ mod tests {
let theta1 = prove_bandwidth_credential(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&sig1,
serial_number,
binding_number,
&serial_number,
&binding_number,
)
.unwrap();
let theta2 = prove_bandwidth_credential(
&params,
&keypair2.verification_key(),
keypair2.verification_key(),
&sig2,
serial_number,
binding_number,
&serial_number,
&binding_number,
)
.unwrap();
assert!(verify_credential(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&theta1,
&[],
));
assert!(verify_credential(
&params,
&keypair2.verification_key(),
keypair2.verification_key(),
&theta2,
&[],
));
assert!(!verify_credential(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&theta2,
&[],
));
@@ -379,30 +413,30 @@ mod tests {
#[test]
fn verification_on_two_public_attributes() {
let mut params = Parameters::new(2).unwrap();
let attributes = params.n_random_scalars(2);
random_scalars_refs!(attributes, params, 2);
let keypair1 = keygen(&params);
let keypair2 = keygen(&params);
let sig1 = sign(&mut params, &keypair1.secret_key(), &attributes).unwrap();
let sig2 = sign(&mut params, &keypair2.secret_key(), &attributes).unwrap();
let sig1 = sign(&mut params, keypair1.secret_key(), &attributes).unwrap();
let sig2 = sign(&mut params, keypair2.secret_key(), &attributes).unwrap();
assert!(verify(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&attributes,
&sig1,
));
assert!(!verify(
&params,
&keypair2.verification_key(),
keypair2.verification_key(),
&attributes,
&sig1,
));
assert!(!verify(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&attributes,
&sig2,
));
@@ -411,10 +445,11 @@ mod tests {
#[test]
fn verification_on_two_public_and_two_private_attributes() {
let params = Parameters::new(4).unwrap();
let public_attributes = params.n_random_scalars(2);
random_scalars_refs!(public_attributes, params, 2);
let serial_number = params.random_scalar();
let binding_number = params.random_scalar();
let private_attributes = vec![serial_number, binding_number];
let private_attributes = vec![&serial_number, &binding_number];
let keypair1 = keygen(&params);
let keypair2 = keygen(&params);
@@ -422,11 +457,11 @@ mod tests {
let (commitments_openings, lambda) =
prepare_blind_sign(&params, &private_attributes, &public_attributes).unwrap();
let sig1 = blind_sign(&params, &keypair1.secret_key(), &lambda, &public_attributes)
let sig1 = blind_sign(&params, keypair1.secret_key(), &lambda, &public_attributes)
.unwrap()
.unblind(
.unblind_and_verify(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&private_attributes,
&public_attributes,
&lambda.get_commitment_hash(),
@@ -434,11 +469,11 @@ mod tests {
)
.unwrap();
let sig2 = blind_sign(&params, &keypair2.secret_key(), &lambda, &public_attributes)
let sig2 = blind_sign(&params, keypair2.secret_key(), &lambda, &public_attributes)
.unwrap()
.unblind(
.unblind_and_verify(
&params,
&keypair2.verification_key(),
keypair2.verification_key(),
&private_attributes,
&public_attributes,
&lambda.get_commitment_hash(),
@@ -448,39 +483,39 @@ mod tests {
let theta1 = prove_bandwidth_credential(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&sig1,
serial_number,
binding_number,
&serial_number,
&binding_number,
)
.unwrap();
let theta2 = prove_bandwidth_credential(
&params,
&keypair2.verification_key(),
keypair2.verification_key(),
&sig2,
serial_number,
binding_number,
&serial_number,
&binding_number,
)
.unwrap();
assert!(verify_credential(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&theta1,
&public_attributes,
));
assert!(verify_credential(
&params,
&keypair2.verification_key(),
keypair2.verification_key(),
&theta2,
&public_attributes,
));
assert!(!verify_credential(
&params,
&keypair1.verification_key(),
keypair1.verification_key(),
&theta2,
&public_attributes,
));
@@ -489,10 +524,11 @@ mod tests {
#[test]
fn verification_on_two_public_and_two_private_attributes_from_two_signers() {
let params = Parameters::new(4).unwrap();
let public_attributes = params.n_random_scalars(2);
random_scalars_refs!(public_attributes, params, 2);
let serial_number = params.random_scalar();
let binding_number = params.random_scalar();
let private_attributes = vec![serial_number, binding_number];
let private_attributes = vec![&serial_number, &binding_number];
let keypairs = ttp_keygen(&params, 2, 3).unwrap();
@@ -502,11 +538,11 @@ mod tests {
let sigs = keypairs
.iter()
.map(|keypair| {
blind_sign(&params, &keypair.secret_key(), &lambda, &public_attributes)
blind_sign(&params, keypair.secret_key(), &lambda, &public_attributes)
.unwrap()
.unblind(
.unblind_and_verify(
&params,
&keypair.verification_key(),
keypair.verification_key(),
&private_attributes,
&public_attributes,
&lambda.get_commitment_hash(),
@@ -518,7 +554,7 @@ mod tests {
let vks = keypairs
.into_iter()
.map(|keypair| keypair.verification_key())
.map(|keypair| keypair.verification_key().clone())
.collect::<Vec<_>>();
let mut attributes = Vec::with_capacity(private_attributes.len() + public_attributes.len());
@@ -530,9 +566,14 @@ mod tests {
aggregate_signatures(&params, &aggr_vk, &attributes, &sigs[..2], Some(&[1, 2]))
.unwrap();
let theta =
prove_bandwidth_credential(&params, &aggr_vk, &aggr_sig, serial_number, binding_number)
.unwrap();
let theta = prove_bandwidth_credential(
&params,
&aggr_vk,
&aggr_sig,
&serial_number,
&binding_number,
)
.unwrap();
assert!(verify_credential(
&params,
@@ -547,9 +588,14 @@ mod tests {
aggregate_signatures(&params, &aggr_vk, &attributes, &sigs[1..], Some(&[2, 3]))
.unwrap();
let theta =
prove_bandwidth_credential(&params, &aggr_vk, &aggr_sig, serial_number, binding_number)
.unwrap();
let theta = prove_bandwidth_credential(
&params,
&aggr_vk,
&aggr_sig,
&serial_number,
&binding_number,
)
.unwrap();
assert!(verify_credential(
&params,
+26 -18
View File
@@ -43,6 +43,8 @@ impl TryFrom<&[u8]> for Theta {
));
}
// safety: we just checked for the length so the unwraps are fine
#[allow(clippy::unwrap_used)]
let blinded_message_bytes = bytes[..96].try_into().unwrap();
let blinded_message = try_deserialize_g2_projective(
&blinded_message_bytes,
@@ -51,6 +53,8 @@ impl TryFrom<&[u8]> for Theta {
),
)?;
// safety: we just checked for the length so the unwraps are fine
#[allow(clippy::unwrap_used)]
let blinded_serial_number_bytes = bytes[96..192].try_into().unwrap();
let blinded_serial_number = try_deserialize_g2_projective(
&blinded_serial_number_bytes,
@@ -130,7 +134,7 @@ impl Base58 for Theta {}
pub fn compute_kappa(
params: &Parameters,
verification_key: &VerificationKey,
private_attributes: &[Attribute],
private_attributes: &[&Attribute],
blinding_factor: Scalar,
) -> G2Projective {
params.gen2() * blinding_factor
@@ -138,11 +142,11 @@ pub fn compute_kappa(
+ private_attributes
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(priv_attr, beta_i)| beta_i * priv_attr)
.map(|(&priv_attr, beta_i)| beta_i * priv_attr)
.sum::<G2Projective>()
}
pub fn compute_zeta(params: &Parameters, serial_number: Attribute) -> G2Projective {
pub fn compute_zeta(params: &Parameters, serial_number: &Attribute) -> G2Projective {
params.gen2() * serial_number
}
@@ -150,8 +154,8 @@ pub fn prove_bandwidth_credential(
params: &Parameters,
verification_key: &VerificationKey,
signature: &Signature,
serial_number: Attribute,
binding_number: Attribute,
serial_number: &Attribute,
binding_number: &Attribute,
) -> Result<Theta> {
if verification_key.beta_g2.len() < 2 {
return Err(
@@ -171,7 +175,7 @@ pub fn prove_bandwidth_credential(
// Thus, we need kappa which allows us to verify sigma'. In particular,
// kappa is computed on m as input, but thanks to the use or random value r,
// it does not reveal any information about m.
let private_attributes = vec![serial_number, binding_number];
let private_attributes = [serial_number, binding_number];
let blinded_message = compute_kappa(
params,
verification_key,
@@ -185,8 +189,8 @@ pub fn prove_bandwidth_credential(
let pi_v = ProofKappaZeta::construct(
params,
verification_key,
&serial_number,
&binding_number,
serial_number,
binding_number,
&sign_blinding_factor,
&blinded_message,
&blinded_serial_number,
@@ -221,7 +225,10 @@ pub fn check_vk_pairing(
if values_len == 0 || values_len - 1 != vk.beta_g1.len() || values_len - 1 != vk.beta_g2.len() {
return false;
}
if vk.alpha != *dkg_values.last().unwrap() {
// safety: we made an explicit check for if the length of the slice is 0, thus unwrap here is fine
#[allow(clippy::unwrap_used)]
if &vk.alpha != *dkg_values.last().as_ref().unwrap() {
return false;
}
if dkg_values
@@ -249,7 +256,7 @@ pub fn verify_credential(
params: &Parameters,
verification_key: &VerificationKey,
theta: &Theta,
public_attributes: &[Attribute],
public_attributes: &[&Attribute],
) -> bool {
if public_attributes.len() + theta.pi_v.private_attributes_len()
> verification_key.beta_g2.len()
@@ -272,7 +279,7 @@ pub fn verify_credential(
.iter()
.skip(theta.pi_v.private_attributes_len()),
)
.map(|(pub_attr, beta_i)| beta_i * pub_attr)
.map(|(&pub_attr, beta_i)| beta_i * pub_attr)
.sum::<G2Projective>();
theta.blinded_message + signed_public_attributes
@@ -291,14 +298,14 @@ pub fn verify_credential(
pub fn verify(
params: &Parameters,
verification_key: &VerificationKey,
public_attributes: &[Attribute],
public_attributes: &[&Attribute],
sig: &Signature,
) -> bool {
let kappa = (verification_key.alpha
+ public_attributes
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(m_i, b_i)| b_i * m_i)
.map(|(&m_i, b_i)| b_i * m_i)
.sum::<G2Projective>())
.to_affine();
@@ -320,10 +327,11 @@ mod tests {
#[test]
fn vk_pairing() {
let params = setup(2).unwrap();
let vk = keygen(&params).verification_key();
let keypair = keygen(&params);
let vk = keypair.verification_key();
let mut dkg_values = vk.beta_g2.clone();
dkg_values.push(vk.alpha);
assert!(check_vk_pairing(&params, &dkg_values, &vk));
assert!(check_vk_pairing(&params, &dkg_values, vk));
}
#[test]
@@ -340,10 +348,10 @@ mod tests {
let theta = prove_bandwidth_credential(
&params,
&keypair.verification_key(),
keypair.verification_key(),
&signature,
serial_number,
binding_number,
&serial_number,
&binding_number,
)
.unwrap();
+5 -4
View File
@@ -1,6 +1,7 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::random_scalars_refs;
use crate::tests::helpers::tests::generate_dkg_keys;
use crate::{
aggregate_verification_keys, setup, tests::helpers::*, ttp_keygen, verify_credential,
@@ -12,14 +13,14 @@ fn keygen() -> Result<(), CoconutError> {
let params = setup(5)?;
let node_indices = vec![15u64, 248, 33521];
let public_attributes = params.n_random_scalars(2);
random_scalars_refs!(public_attributes, params, 2);
// generate_keys
let coconut_keypairs = ttp_keygen(&params, 2, 3)?;
let verification_keys: Vec<VerificationKey> = coconut_keypairs
.iter()
.map(|keypair| keypair.verification_key())
.map(|keypair| keypair.verification_key().clone())
.collect();
// aggregate verification keys
@@ -50,14 +51,14 @@ fn dkg() -> Result<(), CoconutError> {
let params = setup(5)?;
let node_indices = vec![15u64, 248, 33521];
let public_attributes = params.n_random_scalars(2);
random_scalars_refs!(public_attributes, params, 2);
// generate_keys
let coconut_keypairs = generate_dkg_keys(5, &node_indices);
let verification_keys: Vec<VerificationKey> = coconut_keypairs
.iter()
.map(|keypair| keypair.verification_key())
.map(|keypair| keypair.verification_key().clone())
.collect();
// aggregate verification keys
+22 -7
View File
@@ -5,15 +5,17 @@ use crate::*;
use itertools::izip;
use std::fmt::Debug;
// unwraps are fine in the test code
#[allow(clippy::unwrap_used)]
pub fn theta_from_keys_and_attributes(
params: &Parameters,
coconut_keypairs: &Vec<KeyPair>,
indices: &[scheme::SignerIndex],
public_attributes: &Vec<PublicAttribute>,
public_attributes: &[&PublicAttribute],
) -> Result<Theta, CoconutError> {
let serial_number = params.random_scalar();
let binding_number = params.random_scalar();
let private_attributes = vec![serial_number, binding_number];
let private_attributes = vec![&serial_number, &binding_number];
// generate commitment
let (commitments_openings, blind_sign_request) =
@@ -21,7 +23,7 @@ pub fn theta_from_keys_and_attributes(
let verification_keys: Vec<VerificationKey> = coconut_keypairs
.iter()
.map(|keypair| keypair.verification_key())
.map(|keypair| keypair.verification_key().clone())
.collect();
// aggregate verification keys
@@ -33,7 +35,7 @@ pub fn theta_from_keys_and_attributes(
for keypair in coconut_keypairs {
let blinded_signature = blind_sign(
params,
&keypair.secret_key(),
keypair.secret_key(),
&blind_sign_request,
public_attributes,
)?;
@@ -49,7 +51,7 @@ pub fn theta_from_keys_and_attributes(
.map(|(idx, s, vk)| {
(
*idx,
s.unblind(
s.unblind_and_verify(
params,
vk,
&private_attributes,
@@ -81,13 +83,15 @@ pub fn theta_from_keys_and_attributes(
params,
&verification_key,
&signature,
serial_number,
binding_number,
&serial_number,
&binding_number,
)?;
Ok(theta)
}
// unwraps are fine in the test code
#[allow(clippy::unwrap_used)]
pub fn transpose_matrix<T: Debug>(matrix: Vec<Vec<T>>) -> Vec<Vec<T>> {
if matrix.is_empty() {
return vec![];
@@ -104,6 +108,17 @@ pub fn transpose_matrix<T: Debug>(matrix: Vec<Vec<T>>) -> Vec<Vec<T>> {
.collect::<Vec<_>>()
}
#[macro_export]
macro_rules! random_scalars_refs {
( $x: ident, $params: expr, $n: expr ) => {
let _vec = $params.n_random_scalars($n);
#[allow(clippy::map_identity)]
let $x = _vec.iter().collect::<Vec<_>>();
};
}
pub use random_scalars_refs;
#[cfg(test)]
pub mod tests {
use super::*;
+68 -1
View File
@@ -1,4 +1,13 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#![warn(clippy::expect_used)]
#![warn(clippy::unwrap_used)]
use crate::CoconutError;
use bls12_381::{G1Affine, G1Projective, Scalar};
use group::GroupEncoding;
use std::convert::TryInto;
pub trait Bytable
where
@@ -14,9 +23,67 @@ where
Self: Bytable,
{
fn try_from_bs58<S: AsRef<str>>(x: S) -> Result<Self, CoconutError> {
Self::try_from_byte_slice(&bs58::decode(x.as_ref()).into_vec().unwrap())
let bs58_decoded = &bs58::decode(x.as_ref()).into_vec()?;
Self::try_from_byte_slice(bs58_decoded)
}
fn to_bs58(&self) -> String {
bs58::encode(self.to_byte_vec()).into_string()
}
}
impl Bytable for Scalar {
fn to_byte_vec(&self) -> Vec<u8> {
self.to_bytes().to_vec()
}
fn try_from_byte_slice(slice: &[u8]) -> Result<Self, CoconutError> {
let received = slice.len();
let Ok(arr) = slice.try_into() else {
return Err(CoconutError::UnexpectedArrayLength {
typ: "Scalar".to_string(),
received,
expected: 32,
});
};
let maybe_scalar = Scalar::from_bytes(arr);
if maybe_scalar.is_none().into() {
Err(CoconutError::ScalarDeserializationFailure)
} else {
// safety: this unwrap is fine as we've just checked the element is not none
#[allow(clippy::unwrap_used)]
Ok(maybe_scalar.unwrap())
}
}
}
impl Base58 for Scalar {}
impl Bytable for G1Projective {
fn to_byte_vec(&self) -> Vec<u8> {
self.to_bytes().as_ref().to_vec()
}
fn try_from_byte_slice(slice: &[u8]) -> Result<Self, CoconutError> {
let received = slice.len();
let arr: Result<[u8; 48], _> = slice.try_into();
let Ok(bytes) = arr else {
return Err(CoconutError::UnexpectedArrayLength {
typ: "G1Projective".to_string(),
received,
expected: 48,
});
};
let maybe_g1 = G1Affine::from_compressed(&bytes);
if maybe_g1.is_none().into() {
Err(CoconutError::G1ProjectiveDeserializationFailure)
} else {
// safety: this unwrap is fine as we've just checked the element is not none
#[allow(clippy::unwrap_used)]
Ok(maybe_g1.unwrap().into())
}
}
}
impl Base58 for G1Projective {}
+3
View File
@@ -34,6 +34,7 @@ impl Polynomial {
// just return the last term of the polynomial
} else if x.is_zero().into() {
// we checked that coefficients are not empty so unwrap here is fine
#[allow(clippy::unwrap_used)]
*self.coefficients.first().unwrap()
} else {
self.coefficients
@@ -148,6 +149,8 @@ pub(crate) fn try_deserialize_scalar_vec(
let mut out = Vec::with_capacity(expected_len as usize);
for i in 0..expected_len as usize {
// we just checked we have exactly the amount of bytes we need and thus the unwrap is fine
#[allow(clippy::unwrap_used)]
let s_bytes = bytes[i * 32..(i + 1) * 32].try_into().unwrap();
let s = match Into::<Option<Scalar>>::into(Scalar::from_bytes(&s_bytes)) {
None => return Err(err),

Some files were not shown because too many files have changed in this diff Show More