From 83c755e7c1d114b22d92ec5232306ee3e4b2b1b1 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 15 Sep 2023 14:10:52 -0600 Subject: [PATCH 1/7] Set up and document 'verify_signature' method --- API.md | 114 ++++--- Cargo.lock | 740 +++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 1 + candid/ic_eth.did | 1 + src/main.rs | 19 ++ 5 files changed, 824 insertions(+), 51 deletions(-) diff --git a/API.md b/API.md index 9d6f4469..1c345a97 100644 --- a/API.md +++ b/API.md @@ -11,62 +11,20 @@ View this [reference site](https://chainlist.org/?testnets=true) for a list of a ## Methods -### `register_provider` +### `verify_signature` -Register a new provider for a Web2-based service. +Confirm the authenticity of a message signed by an Ethereum private key. Check out [this article](https://programtheblockchain.com/posts/2018/02/17/signing-and-verifying-messages-in-ethereum/) to learn more about Ethereum ECDSA signatures. -```candid -type RegisterProvider = record { - chain_id: nat64; - base_url: text; - credential_path: text; - cycles_per_call: nat64; - cycles_per_message_byte: nat64; -}; + verify_signature : (eth_address: vec nat8, message: vec nat8, signature: vec nat8) -> (bool) query; -register_provider: (RegisterProvider) -> (); -``` +* `eth_address`: A binary-encoded Ethereum wallet address (20 bytes). +* `message`: An arbitrary binary message corresponding to the signature. +* `signature`: An Ethereum ECDSA signature (65 bytes). A common way to generate a signature is via the [`personal_sign` RPC method in MetaMask](https://docs.metamask.io/wallet/how-to/sign-data/#use-personal_sign). -The `RegisterProvider` record defines the details about the service to register, including the API key for the service. -* `chain_id`: The id of the Ethereum chain this provider allows to connect to. The ids refer to the chain ids as defined for EVM-compatible blockchains, see, e.g., [ChainList](https://chainlist.org/?testnets=true). -* `base_url`: The URLs of the Web2 service provider that is used by the canister when using this provider. -* `credential_path`: A path containing API key for authorizing requests to this service provider. This part of the path is private to the entity registering it and the canister. It is not exposed in the response of the `get_providers` method. The URL used to access the service is constructed by concatenating the `base_url` and the `credential_path` (without a seperator), e.g., `"https://cloudflare-eth.com"` and `"/my-api-key"`. -* `cycles_per_call`: Cycles charged per call by the canister in addition to the base charges when using this provider. -* `cycles_per_message_byte`: Cycles charged per payload byte by the canister in addition to the base charges when using this provider. - -The cycles charged can, for example, be used by the entity providing the API key to amortize the API key costs in the case of commercial API keys. A provider record can be removed by its owner principal or a pricipal with administrative permissions. - -### `get_providers` - -Returns a list of currently registered `RegisteredProvider` entries of the canister. - -```candid -type RegisteredProvider = record { - provider_id: nat64; - owner: principal; - chain_id: nat64; - base_url: text; - cycles_per_call: nat64; - cycles_per_message_byte: nat64; -}; - -get_providers: () -> (vec RegisteredProvider) query; -``` - -`vec RegisteredProvider` is a list of providers, each of which represents one provider that has been registered with the canister and corresponds to a registration of an API key for a specific external API service and chain id. A provider entry also contains the cycles price for using this provider, in addition to what is charged for the canister services. - -* `provider_id`: A unique id per registered provider generated by the canister during provider registration. -* `owner`: The principal that has registered the provider and is authorized to unregister it. -* `chain_id`: See `RegisterProvider`. -* `service _url`: See `RegisterProvider`. -* `cycles_per_call`: See `RegisterProvider`. -* `cycles_per_message_byte`: See `RegisterProvider`. - -Clients of this canister need to select a provider that matches w.r.t. the `chain_id` the network they intend to connect to. If multiple providers are available for a given `chain_id`, the per-message or per-byte price or the entity behind the provider (this can be inferred from the `base_url`) may be factors to choose a suitable provider. ### `request` -Make a request to a Web2 Ethereum node using the caller's URL to an openly available JSON-RPC service, or the caller's URL including an API key for an access-protected API provider. No registered API key of the canister is used in this scenario. +Make a request to a Web2 Ethereum node using the caller's URL to an openly available JSON-RPC service, or the caller's URL (including an API key if necessary). No registered API key of the canister is used in this scenario. request: (service_url: text, json_rpc_payload: text, max_response_bytes: nat64) -> (EthRpcResult); @@ -75,6 +33,7 @@ Make a request to a Web2 Ethereum node using the caller's URL to an openly avail * `max_response_bytes`: The expected maximum size of the response of the Web2 API server. This parameter determines the network response size that is charged for. Not specifying it or it being larger than required may lead to substantial extra cycles cost for the HTTPS outcalls mechanism as its (large) default value is used and charged for. * `EthRpcResult`: The response comprises the JSON-encoded result or error, see the corresponding type. + ### `provider_request` Make a request to a Web2 Ethereum node using a registered provider for a JSON-RPC service. There is no need for the client to have any established relationship with the API service. @@ -96,6 +55,7 @@ Calculate the cost of sending a request with the given input arguments. * `json_rpc_payload`: See `request`. * `max_response_bytes`: See `request`. + ### `provider_request_cost` Calculate the cost of sending a request with the given input arguments. @@ -106,6 +66,61 @@ Calculate the cost of sending a request with the given input arguments. * `json_rpc_payload`: See `request_cost`. * `max_response_bytes`: See `request_cost`. +### `get_providers` + +Returns a list of currently registered `RegisteredProvider` entries of the canister. + +```candid +type RegisteredProvider = record { + provider_id: nat64; + owner: principal; + chain_id: nat64; + base_url: text; + cycles_per_call: nat64; + cycles_per_message_byte: nat64; +}; + +get_providers: () -> (vec RegisteredProvider) query; +``` + +`vec RegisteredProvider` is a list of providers, each of which represents one provider that has been registered with the canister and corresponds to a registration of an API key for a specific external API service and chain id. A provider entry also contains the cycles price for using this provider, in addition to what is charged for the canister services. + +* `provider_id`: A unique id per registered provider generated by the canister during provider registration. +* `owner`: The principal that has registered the provider and is authorized to unregister it. +* `chain_id`: See `RegisterProvider`. +* `service _url`: See `RegisterProvider`. +* `cycles_per_call`: See `RegisterProvider`. +* `cycles_per_message_byte`: See `RegisterProvider`. + +Clients of this canister need to select a provider that matches w.r.t. the `chain_id` the network they intend to connect to. If multiple providers are available for a given `chain_id`, the per-message or per-byte price or the entity behind the provider (this can be inferred from the `base_url`) may be factors to choose a suitable provider. + + +### `register_provider` + +Register a new provider for a Web2-based service. + +```candid +type RegisterProvider = record { + chain_id: nat64; + base_url: text; + credential_path: text; + cycles_per_call: nat64; + cycles_per_message_byte: nat64; +}; + +register_provider: (RegisterProvider) -> (); +``` + +The `RegisterProvider` record defines the details about the service to register, including the API key for the service. +* `chain_id`: The id of the Ethereum chain this provider allows to connect to. The ids refer to the chain ids as defined for EVM-compatible blockchains, see, e.g., [ChainList](https://chainlist.org/?testnets=true). +* `base_url`: The URLs of the Web2 service provider that is used by the canister when using this provider. +* `credential_path`: A path containing API key for authorizing requests to this service provider. This part of the path is private to the entity registering it and the canister. It is not exposed in the response of the `get_providers` method. The URL used to access the service is constructed by concatenating the `base_url` and the `credential_path` (without a seperator), e.g., `"https://cloudflare-eth.com"` and `"/my-api-key"`. +* `cycles_per_call`: Cycles charged per call by the canister in addition to the base charges when using this provider. +* `cycles_per_message_byte`: Cycles charged per payload byte by the canister in addition to the base charges when using this provider. + +The cycles charged can, for example, be used by the entity providing the API key to amortize the API key costs in the case of commercial API keys. A provider record can be removed by its owner principal or a pricipal with administrative permissions. + + ### `unregister_provider` Unregister a provider from the canister. Only the owner of the provider or an admin principal is authorized to perform this action. @@ -116,6 +131,7 @@ unregister_provider: (provider_id: nat64) -> (); The `provider_id` for the provider to be unregistered is the only parameter required. + ### `authorize` Used for authorizing a principal for certain classes of actions as defined through `Auth`. diff --git a/Cargo.lock b/Cargo.lock index a7bab644..dc081c6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,6 +23,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "ascii-canvas" version = "3.0.0" @@ -32,12 +38,36 @@ dependencies = [ "term", ] +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "beef" version = "0.5.2" @@ -94,6 +124,18 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -103,12 +145,27 @@ dependencies = [ "generic-array", ] +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] + [[package]] name = "candid" version = "0.8.4" @@ -204,6 +261,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "num-traits", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -214,6 +280,24 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "const-hex" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08849ed393c907c90016652a01465a12d86361cd38ad2a7de026c56a520cc259" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + [[package]] name = "cpufeatures" version = "0.2.9" @@ -238,6 +322,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -254,6 +350,27 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "diff" version = "0.1.13" @@ -267,7 +384,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", + "subtle", ] [[package]] @@ -291,12 +410,45 @@ dependencies = [ "winapi", ] +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + [[package]] name = "either" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "ena" version = "0.14.2" @@ -333,6 +485,109 @@ dependencies = [ "libc", ] +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers-core" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a17f0708692024db9956b31d7a20163607d2745953f5ae8125ab368ba280ad" +dependencies = [ + "arrayvec 0.7.4", + "bytes", + "chrono", + "const-hex", + "elliptic-curve", + "ethabi", + "generic-array", + "k256", + "num_enum 0.7.0", + "open-fastrlp", + "rand", + "rlp", + "serde", + "serde_json", + "strum", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -354,6 +609,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "generic-array" version = "0.14.7" @@ -362,6 +623,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -375,6 +637,17 @@ dependencies = [ "wasi", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "half" version = "1.8.2" @@ -393,6 +666,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.3.2" @@ -405,6 +684,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "ic-canister-log" version = "0.2.0" @@ -461,6 +749,22 @@ dependencies = [ "sha2", ] +[[package]] +name = "ic-eth" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dadba2b8277c9b3299ebdaf5031b0e957c648bab3117ac444bad76a886afee" +dependencies = [ + "ethers-core", + "getrandom", + "hex", + "ic-cdk", + "ic-cdk-macros", + "serde", + "serde_json", + "url", +] + [[package]] name = "ic-metrics-encoder" version = "1.1.0" @@ -489,6 +793,7 @@ dependencies = [ "ic-cdk", "ic-cdk-macros", "ic-certified-map", + "ic-eth", "ic-metrics-encoder", "ic-stable-structures", "json5", @@ -512,6 +817,44 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -552,6 +895,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + [[package]] name = "json5" version = "0.4.1" @@ -563,6 +912,28 @@ dependencies = [ "serde", ] +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lalrpop" version = "0.19.12" @@ -839,6 +1210,15 @@ dependencies = [ "num_enum_derive 0.6.1", ] +[[package]] +name = "num_enum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +dependencies = [ + "num_enum_derive 0.7.0", +] + [[package]] name = "num_enum_derive" version = "0.5.11" @@ -863,12 +1243,75 @@ dependencies = [ "syn 2.0.23", ] +[[package]] +name = "num_enum_derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.23", +] + [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec 0.7.4", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756d439303e94fae44f288ba881ad29670c65b0c4b0e05674ca81061bb65f2c5" +dependencies = [ + "arrayvec 0.7.4", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d884d78fcf214d70b1e239fcd1c6e5e95aa3be1881918da2e488cc946c7a476" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -973,6 +1416,22 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "precomputed-hash" version = "0.1.1" @@ -985,7 +1444,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad9940b913ee56ddd94aec2d3cd179dd47068236f42a1a6415ccf9d880ce2a61" dependencies = [ - "arrayvec", + "arrayvec 0.5.2", "typed-arena", ] @@ -995,11 +1454,25 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "563c9d701c3a31dfffaaf9ce23507ba09cbe0b9125ba176d15e629b0235e9acc" dependencies = [ - "arrayvec", + "arrayvec 0.5.2", "typed-arena", "unicode-segmentation", ] +[[package]] +name = "primitive-types" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -1010,6 +1483,30 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.63" @@ -1037,6 +1534,42 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1101,6 +1634,44 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + [[package]] name = "rustix" version = "0.38.3" @@ -1120,12 +1691,56 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "scale-info" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "serde" version = "1.0.168" @@ -1165,6 +1780,17 @@ dependencies = [ "syn 2.0.23", ] +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_tokenstream" version = "0.1.7" @@ -1187,6 +1813,26 @@ dependencies = [ "digest", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "siphasher" version = "0.3.10" @@ -1199,6 +1845,16 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stacker" version = "0.1.15" @@ -1212,6 +1868,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "string_cache" version = "0.8.7" @@ -1225,6 +1887,34 @@ dependencies = [ "precomputed-hash", ] +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.23", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "1.0.109" @@ -1247,6 +1937,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys", +] + [[package]] name = "term" version = "0.7.0" @@ -1346,6 +2055,18 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -1513,3 +2234,18 @@ checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" dependencies = [ "memchr", ] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/Cargo.toml b/Cargo.toml index f4fe3921..a7913f19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ ic-canisters-http-types = { git = "https://github.com/dfinity/ic", rev = "releas ic-certified-map = "0.4" ic-cdk = "0.10" ic-cdk-macros = "0.7" +ic-eth = "0.0" ic-metrics-encoder = "1.1" ic-stable-structures = "0.5" json5 = "0.4" diff --git a/candid/ic_eth.did b/candid/ic_eth.did index 02215c3a..c0124a45 100644 --- a/candid/ic_eth.did +++ b/candid/ic_eth.did @@ -41,5 +41,6 @@ service : { set_open_rpc_access : (bool) -> (); unregister_provider : (nat64) -> (); update_provider_credential : (nat64, text) -> (); + verify_signature : (vec nat8, vec nat8, vec nat8) -> (bool) query; withdraw_owed_cycles : (nat64, principal) -> (); } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c5d67d9b..0cde84eb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use candid::{candid_method, CandidType}; use ic_canister_log::log; use ic_cdk::api::management_canister::http_request::{HttpHeader, HttpResponse, TransformArgs}; use ic_cdk::{query, update}; +use ic_eth::core::types::{Address, RecoveryMessage, Signature}; // use ic_canisters_http_types::{ // HttpRequest as AssetHttpRequest, HttpResponse as AssetHttpResponse, HttpResponseBuilder, // }; @@ -9,6 +10,24 @@ use ic_cdk::{query, update}; use ic_eth_rpc::*; +#[ic_cdk_macros::query] +#[candid_method(query)] +pub fn verify_signature(eth_address: Vec, message: Vec, signature: Vec) -> bool { + if signature.len() != 65 { + ic_cdk::trap("expected 65-byte signature"); + } + Signature { + r: signature[..32].into(), + s: signature[32..64].into(), + v: signature[64].into(), + } + .verify( + RecoveryMessage::Data(message), + Address::from_slice(ð_address), + ) + .is_ok() +} + #[update] #[candid_method] async fn request( From 71cf9272c76c3b4086df058781d9487efc103ac1 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 15 Sep 2023 14:13:55 -0600 Subject: [PATCH 2/7] Refactor to 'signature' module --- src/lib.rs | 2 ++ src/main.rs | 15 +-------------- src/signature.rs | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 src/signature.rs diff --git a/src/lib.rs b/src/lib.rs index 95220407..f9cc52d8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ mod constants; mod http; mod memory; mod metrics; +mod signature; mod types; mod util; mod validate; @@ -16,6 +17,7 @@ pub use crate::constants::*; pub use crate::http::*; pub use crate::memory::*; pub use crate::metrics::*; +pub use crate::signature::*; pub use crate::types::*; pub use crate::util::*; pub use crate::validate::*; diff --git a/src/main.rs b/src/main.rs index 0cde84eb..187c5ab5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,6 @@ use candid::{candid_method, CandidType}; use ic_canister_log::log; use ic_cdk::api::management_canister::http_request::{HttpHeader, HttpResponse, TransformArgs}; use ic_cdk::{query, update}; -use ic_eth::core::types::{Address, RecoveryMessage, Signature}; // use ic_canisters_http_types::{ // HttpRequest as AssetHttpRequest, HttpResponse as AssetHttpResponse, HttpResponseBuilder, // }; @@ -13,19 +12,7 @@ use ic_eth_rpc::*; #[ic_cdk_macros::query] #[candid_method(query)] pub fn verify_signature(eth_address: Vec, message: Vec, signature: Vec) -> bool { - if signature.len() != 65 { - ic_cdk::trap("expected 65-byte signature"); - } - Signature { - r: signature[..32].into(), - s: signature[32..64].into(), - v: signature[64].into(), - } - .verify( - RecoveryMessage::Data(message), - Address::from_slice(ð_address), - ) - .is_ok() + do_verify_signature(eth_address, message, signature) } #[update] diff --git a/src/signature.rs b/src/signature.rs new file mode 100644 index 00000000..f352ba01 --- /dev/null +++ b/src/signature.rs @@ -0,0 +1,17 @@ +use ic_eth::core::types::{Address, RecoveryMessage, Signature}; + +pub fn do_verify_signature(eth_address: Vec, message: Vec, signature: Vec) -> bool { + if signature.len() != 65 { + ic_cdk::trap("expected 65-byte signature"); + } + Signature { + r: signature[..32].into(), + s: signature[32..64].into(), + v: signature[64].into(), + } + .verify( + RecoveryMessage::Data(message), + Address::from_slice(ð_address), + ) + .is_ok() +} From 2b15230e18b81910013f163bfe3a0db1bd655203 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 15 Sep 2023 14:22:10 -0600 Subject: [PATCH 3/7] Optimize verify logic --- src/signature.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/signature.rs b/src/signature.rs index f352ba01..4146111d 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -1,6 +1,9 @@ -use ic_eth::core::types::{Address, RecoveryMessage, Signature}; +use ic_eth::core::types::{RecoveryMessage, Signature}; pub fn do_verify_signature(eth_address: Vec, message: Vec, signature: Vec) -> bool { + let eth_address_bytes: [u8; 20] = eth_address + .try_into() + .unwrap_or_else(|_| ic_cdk::trap("expected 20-byte address")); if signature.len() != 65 { ic_cdk::trap("expected 65-byte signature"); } @@ -9,9 +12,11 @@ pub fn do_verify_signature(eth_address: Vec, message: Vec, signature: Ve s: signature[32..64].into(), v: signature[64].into(), } - .verify( - RecoveryMessage::Data(message), - Address::from_slice(ð_address), - ) + .verify(RecoveryMessage::Data(message), eth_address_bytes) .is_ok() } + +#[test] +fn test_verify_signature() { + // TODO +} From 10514a4179124a116562f7064a83473bdf2e3de3 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 15 Sep 2023 14:35:02 -0600 Subject: [PATCH 4/7] Add tests for signature verification --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 2 +- src/signature.rs | 31 +++++++++++++++++++++++++++++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc081c6e..af811177 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -788,6 +788,7 @@ name = "ic_eth_rpc" version = "0.1.0" dependencies = [ "candid 0.9.2", + "hex", "ic-canister-log", "ic-canisters-http-types", "ic-cdk", diff --git a/Cargo.toml b/Cargo.toml index a7913f19..c8caa07f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,3 +34,4 @@ url = "2.4" [dev-dependencies] candid = { features = ["parser"] } +hex = "0.4" diff --git a/src/main.rs b/src/main.rs index 187c5ab5..90932f31 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use ic_eth_rpc::*; #[ic_cdk_macros::query] #[candid_method(query)] pub fn verify_signature(eth_address: Vec, message: Vec, signature: Vec) -> bool { - do_verify_signature(eth_address, message, signature) + do_verify_signature(ð_address, message, signature) } #[update] diff --git a/src/signature.rs b/src/signature.rs index 4146111d..8c1b7122 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -1,6 +1,6 @@ use ic_eth::core::types::{RecoveryMessage, Signature}; -pub fn do_verify_signature(eth_address: Vec, message: Vec, signature: Vec) -> bool { +pub fn do_verify_signature(eth_address: &[u8], message: Vec, signature: Vec) -> bool { let eth_address_bytes: [u8; 20] = eth_address .try_into() .unwrap_or_else(|_| ic_cdk::trap("expected 20-byte address")); @@ -18,5 +18,32 @@ pub fn do_verify_signature(eth_address: Vec, message: Vec, signature: Ve #[test] fn test_verify_signature() { - // TODO + let address = &hex::decode("c9b28dca7ea6c5e176a58ba9df53c30ba52c6642").unwrap(); + let message = "hello".as_bytes().to_vec(); + let signature = hex::decode("5c0e32248c10f7125b32cae1de9988f2dab686031083302f85b0a82f78e9206516b272fb7641f3e8ab63cf9f3a9b9220b2d6ff2699dc34f0d000d7693ca1ea5e1c").unwrap(); + + let other_message = "other".as_bytes().to_vec(); + let other_signature = hex::decode("27ae1f90fd65c86b07aae1287dba8715db7e429ff9bf700205cb8ac904c6ba071c8fb7c6f8b5e15338521fee95a452c6a688f1c6fec5eeddbfa680a2abf300341b").unwrap(); + + // Valid signature + assert_eq!( + do_verify_signature(address, message.clone(), signature.clone()), + true + ); + assert_eq!( + do_verify_signature(address, other_message.clone(), other_signature.clone()), + true + ); + + // Invalid message + assert_eq!( + do_verify_signature(address, other_message.clone(), signature.clone()), + false + ); + + // Invalid signature + assert_eq!( + do_verify_signature(address, message.clone(), other_signature.clone()), + false + ); } From 6c9707a796062dfae5c51746d6afa788ffa44660 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 15 Sep 2023 15:56:11 -0600 Subject: [PATCH 5/7] Fix linter warnings --- src/signature.rs | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/signature.rs b/src/signature.rs index 8c1b7122..c236ac75 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -19,31 +19,20 @@ pub fn do_verify_signature(eth_address: &[u8], message: Vec, signature: Vec< #[test] fn test_verify_signature() { let address = &hex::decode("c9b28dca7ea6c5e176a58ba9df53c30ba52c6642").unwrap(); - let message = "hello".as_bytes().to_vec(); - let signature = hex::decode("5c0e32248c10f7125b32cae1de9988f2dab686031083302f85b0a82f78e9206516b272fb7641f3e8ab63cf9f3a9b9220b2d6ff2699dc34f0d000d7693ca1ea5e1c").unwrap(); - let other_message = "other".as_bytes().to_vec(); - let other_signature = hex::decode("27ae1f90fd65c86b07aae1287dba8715db7e429ff9bf700205cb8ac904c6ba071c8fb7c6f8b5e15338521fee95a452c6a688f1c6fec5eeddbfa680a2abf300341b").unwrap(); + let m1 = "hello".as_bytes().to_vec(); + let s1 = hex::decode("5c0e32248c10f7125b32cae1de9988f2dab686031083302f85b0a82f78e9206516b272fb7641f3e8ab63cf9f3a9b9220b2d6ff2699dc34f0d000d7693ca1ea5e1c").unwrap(); - // Valid signature - assert_eq!( - do_verify_signature(address, message.clone(), signature.clone()), - true - ); - assert_eq!( - do_verify_signature(address, other_message.clone(), other_signature.clone()), - true - ); + let m2 = "other".as_bytes().to_vec(); + let s2 = hex::decode("27ae1f90fd65c86b07aae1287dba8715db7e429ff9bf700205cb8ac904c6ba071c8fb7c6f8b5e15338521fee95a452c6a688f1c6fec5eeddbfa680a2abf300341b").unwrap(); // Invalid message - assert_eq!( - do_verify_signature(address, other_message.clone(), signature.clone()), - false - ); + assert_eq!(do_verify_signature(address, m2.clone(), s1.clone()), false); // Invalid signature - assert_eq!( - do_verify_signature(address, message.clone(), other_signature.clone()), - false - ); + assert_eq!(do_verify_signature(address, m1.clone(), s2.clone()), false); + + // Valid signature + assert_eq!(do_verify_signature(address, m1, s1), true); + assert_eq!(do_verify_signature(address, m2, s2), true); } From a922e87f0d5dbb9bb1628463151d43f70b050da6 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 15 Sep 2023 15:56:11 -0600 Subject: [PATCH 6/7] Fix linter warnings --- src/signature.rs | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/signature.rs b/src/signature.rs index 8c1b7122..c236ac75 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -19,31 +19,20 @@ pub fn do_verify_signature(eth_address: &[u8], message: Vec, signature: Vec< #[test] fn test_verify_signature() { let address = &hex::decode("c9b28dca7ea6c5e176a58ba9df53c30ba52c6642").unwrap(); - let message = "hello".as_bytes().to_vec(); - let signature = hex::decode("5c0e32248c10f7125b32cae1de9988f2dab686031083302f85b0a82f78e9206516b272fb7641f3e8ab63cf9f3a9b9220b2d6ff2699dc34f0d000d7693ca1ea5e1c").unwrap(); - let other_message = "other".as_bytes().to_vec(); - let other_signature = hex::decode("27ae1f90fd65c86b07aae1287dba8715db7e429ff9bf700205cb8ac904c6ba071c8fb7c6f8b5e15338521fee95a452c6a688f1c6fec5eeddbfa680a2abf300341b").unwrap(); + let m1 = "hello".as_bytes().to_vec(); + let s1 = hex::decode("5c0e32248c10f7125b32cae1de9988f2dab686031083302f85b0a82f78e9206516b272fb7641f3e8ab63cf9f3a9b9220b2d6ff2699dc34f0d000d7693ca1ea5e1c").unwrap(); - // Valid signature - assert_eq!( - do_verify_signature(address, message.clone(), signature.clone()), - true - ); - assert_eq!( - do_verify_signature(address, other_message.clone(), other_signature.clone()), - true - ); + let m2 = "other".as_bytes().to_vec(); + let s2 = hex::decode("27ae1f90fd65c86b07aae1287dba8715db7e429ff9bf700205cb8ac904c6ba071c8fb7c6f8b5e15338521fee95a452c6a688f1c6fec5eeddbfa680a2abf300341b").unwrap(); // Invalid message - assert_eq!( - do_verify_signature(address, other_message.clone(), signature.clone()), - false - ); + assert_eq!(do_verify_signature(address, m2.clone(), s1.clone()), false); // Invalid signature - assert_eq!( - do_verify_signature(address, message.clone(), other_signature.clone()), - false - ); + assert_eq!(do_verify_signature(address, m1.clone(), s2.clone()), false); + + // Valid signature + assert_eq!(do_verify_signature(address, m1, s1), true); + assert_eq!(do_verify_signature(address, m2, s2), true); } From f3a5d885cc8f7c2f1ac53cb273c94a055d5ba91f Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 15 Sep 2023 16:02:15 -0600 Subject: [PATCH 7/7] Misc --- src/signature.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/signature.rs b/src/signature.rs index c236ac75..977aeaf2 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -27,12 +27,12 @@ fn test_verify_signature() { let s2 = hex::decode("27ae1f90fd65c86b07aae1287dba8715db7e429ff9bf700205cb8ac904c6ba071c8fb7c6f8b5e15338521fee95a452c6a688f1c6fec5eeddbfa680a2abf300341b").unwrap(); // Invalid message - assert_eq!(do_verify_signature(address, m2.clone(), s1.clone()), false); + assert!(!do_verify_signature(address, m2.clone(), s1.clone())); // Invalid signature - assert_eq!(do_verify_signature(address, m1.clone(), s2.clone()), false); + assert!(!do_verify_signature(address, m1.clone(), s2.clone())); // Valid signature - assert_eq!(do_verify_signature(address, m1, s1), true); - assert_eq!(do_verify_signature(address, m2, s2), true); + assert!(do_verify_signature(address, m1, s1)); + assert!(do_verify_signature(address, m2, s2)); }