wallet: add sign-msg and verify-msg commands (WalletConnect scheme)#4188
wallet: add sign-msg and verify-msg commands (WalletConnect scheme)#4188Copilot wants to merge 6 commits into
Conversation
…g scheme Co-authored-by: roman-khimov <22092804+roman-khimov@users.noreply.github.com>
…word in test Co-authored-by: roman-khimov <22092804+roman-khimov@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #4188 +/- ##
==========================================
- Coverage 83.40% 83.35% -0.06%
==========================================
Files 357 359 +2
Lines 43760 43906 +146
==========================================
+ Hits 36499 36598 +99
- Misses 5464 5496 +32
- Partials 1797 1812 +15 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| // RFC 6979 ECDSA with SHA-256. The returned signature is 64 bytes of ECDSA | ||
| // signature followed by WalletConnectSaltLen bytes of salt (80 bytes total). | ||
| func (p *PrivateKey) SignWalletConnect(data []byte) ([]byte, error) { | ||
| b64 := make([]byte, base64.StdEncoding.EncodedLen(len(data))) |
There was a problem hiding this comment.
Avoid this and other allocations, we only need a hash of this data, so io.Writer of hash.Hash can be leveraged to avoid buffering and copying things around.
There was a problem hiding this comment.
Fixed in commit 3681226. Replaced the intermediate payload buffer with a streaming approach: sha256.New() is used as an io.Writer, and hex.NewEncoder/base64.NewEncoder write directly into the hash — no buffer allocation needed.
| return false | ||
| } | ||
| b64 := make([]byte, base64.StdEncoding.EncodedLen(len(data))) | ||
| base64.StdEncoding.Encode(b64, data) |
| "github.com/urfave/cli/v2" | ||
| ) | ||
|
|
||
| // signMessageResult contains the output of the sign-msg command. |
There was a problem hiding this comment.
Not needed. The output is just a signature.
There was a problem hiding this comment.
Removed in commit 3681226. sign-msg now just prints the hex-encoded 80-byte signature (ECDSA + salt) directly.
| } | ||
|
|
||
| sig := sigWithSalt[:keys.SignatureLen] | ||
| salt := sigWithSalt[keys.SignatureLen:] |
There was a problem hiding this comment.
Fixed in commit 3681226. No longer splitting — SignWalletConnect returns the full 80-byte combined value which is passed directly to output/verify without intermediate slicing.
| return cli.Exit(err, 1) | ||
| } | ||
|
|
||
| saltHex := ctx.String("salt") |
There was a problem hiding this comment.
Fixed in commit 3681226. Removed the --salt flag entirely. --signature now takes the full 80-byte hex value (64-byte ECDSA + 16-byte salt) as produced by sign-msg.
|
@copilot, please fix comments from previous review |
Co-authored-by: roman-khimov <22092804+roman-khimov@users.noreply.github.com>
|
@copilot try again |
…ature param Co-authored-by: roman-khimov <22092804+roman-khimov@users.noreply.github.com>
…test Co-authored-by: roman-khimov <22092804+roman-khimov@users.noreply.github.com>
NeoGo had no way to produce or verify message signatures compatible with Neon/NeoLine and the NeoFS WalletConnect scheme, making it impossible to interoperate with signatures from other Neo wallets.
Changes
pkg/crypto/keys/walletconnect.go— core primitives:(*PrivateKey).SignWalletConnect(data []byte) ([]byte, error)— signs using the WalletConnect scheme; returns 80 bytes (64-byte ECDSA sig + 16-byte random salt)(*PublicKey).VerifyWalletConnect(data, signature []byte) bool— verifies an 80-byte WalletConnect signaturesha256.New()(no intermediate buffer):0x01 0x00 0x01 0xf0 | VarUint(len(hex(salt)+base64(msg))) | hex(salt) | base64(msg) | 0x00 0x00cli/wallet/message.go— two new wallet subcommands:wallet sign-msg— signs an arbitrary message and prints the hex-encoded 80-byte signature (64-byte ECDSA + 16-byte salt)wallet verify-msg— verifies against a public key or wallet addressUsage
Both commands accept
--hexand--base64flags to handle binary messages.verify-msgalso accepts--addresswith a wallet for address-based lookup, extracting the public key from the verification script without requiring private key decryption.The signing payload format is identical to the neofs-sdk-go
SignerWalletConnectimplementation, ensuring cross-wallet compatibility.Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.