From f6f6b566bd479515f651cbb64da85803fb87d0cf Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Fri, 18 Jul 2025 00:45:39 +0100 Subject: [PATCH 1/3] refactor: sign messages eip191 --- src/Utils/Message.php | 16 +++++++++++----- tests/Unit/Utils/MessageTest.php | 6 ++++-- tests/fixtures/message-sign.json | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Utils/Message.php b/src/Utils/Message.php index ca9ad07..2da7076 100644 --- a/src/Utils/Message.php +++ b/src/Utils/Message.php @@ -16,6 +16,8 @@ class Message { + const MESSAGE_PREFIX = "\x19Ethereum Signed Message:\n"; + /** * The message signer public key. * @@ -99,7 +101,7 @@ public static function sign(string $message, string $passphrase): self { $privateKey = PrivateKey::fromPassphrase($passphrase); - $hash = Keccak::hash($message, 256); + $hash = Keccak::hash(static::MESSAGE_PREFIX.strlen($message).$message, 256); $signature = $privateKey->sign(Buffer::hex($hash)); @@ -125,10 +127,14 @@ public function verify(): bool $signature = $this->getSignature(); - return $factory->fromHex($this->publicKey)->verify( - Buffer::hex(Keccak::hash($this->message, 256)), - $signature, - ); + $message = static::MESSAGE_PREFIX.strlen($this->message).$this->message; + + return $factory + ->fromHex($this->publicKey) + ->verify( + Buffer::hex(Keccak::hash($message, 256)), + $signature, + ); } /** diff --git a/tests/Unit/Utils/MessageTest.php b/tests/Unit/Utils/MessageTest.php index 35093fe..60456e9 100644 --- a/tests/Unit/Utils/MessageTest.php +++ b/tests/Unit/Utils/MessageTest.php @@ -10,7 +10,7 @@ $message = Message::sign($fixture['message'], $this->passphrase); expect($message->publicKey)->toBe($fixture['publicKey']); - expect($message->signature)->toBe($fixture['signature']); + expect($message->signature)->toBe(substr($fixture['signature'], 2)); expect($message->message)->toBe($fixture['message']); }); @@ -64,7 +64,9 @@ }); test('it should verify a message', function () { - $message = Message::new($this->getFixture('message-sign')); + $fixture = $this->getFixture('message-sign'); + $fixture['signature'] = substr($fixture['signature'], 2); + $message = Message::new($fixture); expect($message->verify())->toBeTrue(); }); diff --git a/tests/fixtures/message-sign.json b/tests/fixtures/message-sign.json index 88ad8ea..6a96d89 100644 --- a/tests/fixtures/message-sign.json +++ b/tests/fixtures/message-sign.json @@ -1,5 +1,5 @@ { "message": "Hello, world!", "publicKey": "0243333347c8cbf4e3cbc7a96964181d02a2b0c854faa2fef86b4b8d92afcf473d", - "signature": "0e2e53409be748834cac44052817ecef569b429a0492aa6bbc0d934eb71a09547e77aeef33d45669bbcba0498149f0e2b637fe8905186e08a5410c6f2b013bb400" + "signature": "0x2bdd0c58ff8a25f456065fb731c73308a25d0a09f351f23e3c7dd3882776d33d626b0cafc0b99dd7504b24f6ecd2e036a267c8e5e005f36dcbc03b2e33fa7fc301" } From d6fdde71bd843e2776fb30fda310155c35cc5011 Mon Sep 17 00:00:00 2001 From: alexbarnsley Date: Thu, 17 Jul 2025 23:46:29 +0000 Subject: [PATCH 2/3] style: resolve style guide violations --- src/Utils/Message.php | 2 +- tests/Unit/Utils/MessageTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Utils/Message.php b/src/Utils/Message.php index 2da7076..df508a5 100644 --- a/src/Utils/Message.php +++ b/src/Utils/Message.php @@ -16,7 +16,7 @@ class Message { - const MESSAGE_PREFIX = "\x19Ethereum Signed Message:\n"; + public const MESSAGE_PREFIX = "\x19Ethereum Signed Message:\n"; /** * The message signer public key. diff --git a/tests/Unit/Utils/MessageTest.php b/tests/Unit/Utils/MessageTest.php index 60456e9..b3049fe 100644 --- a/tests/Unit/Utils/MessageTest.php +++ b/tests/Unit/Utils/MessageTest.php @@ -64,9 +64,9 @@ }); test('it should verify a message', function () { - $fixture = $this->getFixture('message-sign'); + $fixture = $this->getFixture('message-sign'); $fixture['signature'] = substr($fixture['signature'], 2); - $message = Message::new($fixture); + $message = Message::new($fixture); expect($message->verify())->toBeTrue(); }); From 2ea6c2bb241899d99d57b628df8c3ac85caf21cc Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Fri, 18 Jul 2025 08:29:45 +0100 Subject: [PATCH 3/3] use 27-based signature --- src/Utils/Message.php | 2 +- tests/fixtures/message-sign.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Utils/Message.php b/src/Utils/Message.php index 2da7076..29a2d18 100644 --- a/src/Utils/Message.php +++ b/src/Utils/Message.php @@ -107,7 +107,7 @@ public static function sign(string $message, string $passphrase): self $r = Helpers::gmpToHex($signature->getR()); $s = Helpers::gmpToHex($signature->getS()); - $v = str_pad(dechex($signature->getRecoveryId()), 2, '0', STR_PAD_LEFT); + $v = str_pad(dechex($signature->getRecoveryId() + 27), 2, '0', STR_PAD_LEFT); return static::new([ 'publicKey' => $privateKey->publicKey, diff --git a/tests/fixtures/message-sign.json b/tests/fixtures/message-sign.json index 6a96d89..8cebbc5 100644 --- a/tests/fixtures/message-sign.json +++ b/tests/fixtures/message-sign.json @@ -1,5 +1,5 @@ { "message": "Hello, world!", "publicKey": "0243333347c8cbf4e3cbc7a96964181d02a2b0c854faa2fef86b4b8d92afcf473d", - "signature": "0x2bdd0c58ff8a25f456065fb731c73308a25d0a09f351f23e3c7dd3882776d33d626b0cafc0b99dd7504b24f6ecd2e036a267c8e5e005f36dcbc03b2e33fa7fc301" + "signature": "0x2bdd0c58ff8a25f456065fb731c73308a25d0a09f351f23e3c7dd3882776d33d626b0cafc0b99dd7504b24f6ecd2e036a267c8e5e005f36dcbc03b2e33fa7fc31c" }