From 470a72d4dec9f2f0ad95df9ed6924ad56b08510d Mon Sep 17 00:00:00 2001 From: Wilson Silva Date: Fri, 15 Mar 2024 18:49:40 +0000 Subject: [PATCH] Document how to verify the signature of messages and events --- docs/.vitepress/config.mjs | 2 + .../signing-and-verifying-events.md | 50 +++++++++++++++++++ .../signing-and-verifying-messages.md | 43 ++++++++++++++++ docs/getting-started/overview.md | 1 + 4 files changed, 96 insertions(+) create mode 100644 docs/common-use-cases/signing-and-verifying-events.md create mode 100644 docs/common-use-cases/signing-and-verifying-messages.md diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index 628730d..4e85f84 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -79,6 +79,8 @@ export default defineConfig(withMermaid({ collapsed: false, items: [ { text: 'Bech32 enc/decoding (NIP-19)', link: '/common-use-cases/bech32-encoding-and-decoding-(NIP-19)' }, + { text: 'Signing/verifying messages', link: '/common-use-cases/signing-and-verifying-messages' }, + { text: 'Signing/verifying events', link: '/common-use-cases/signing-and-verifying-events' }, ] }, { diff --git a/docs/common-use-cases/signing-and-verifying-events.md b/docs/common-use-cases/signing-and-verifying-events.md new file mode 100644 index 0000000..ad42d0e --- /dev/null +++ b/docs/common-use-cases/signing-and-verifying-events.md @@ -0,0 +1,50 @@ +# Signing and verifying events + +Signing an event in Nostr proves it was sent by the owner of a specific private key. + +## Signing an event + +To sign an event, use the private key associated with the event's creator. Here's how to sign a message using a +predefined keypair: + +```ruby{14} +require 'nostr' + +private_key = Nostr::PrivateKey.new('67dea2ed018072d675f5415ecfaed7d2597555e202d85b3d65ea4e58d2d92ffa'), +public_key = Nostr::PublicKey.new('7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e'), + +event = Nostr::Event.new( + pubkey: public_key.to_s, + kind: Nostr::EventKind::TEXT_NOTE, + content: 'We did it with security, now we’re going to do it with the economy.', + created_at: Time.now.to_i, +) + +# Sign the event with the private key +event.sign(private_key) + +puts "Event ID: #{event.id}" +puts "Event Signature: #{event.sig}" +``` + +## Verifying an event's signature + +To verify an event, you must ensure the event's signature is valid. This indicates the event was created by the owner +of the corresponding public key. + +When the event was signed with the private key corresponding to the public key, the `verify_signature` method will +return `true`. + +```ruby +event.verify_signature # => true +``` + +And when the event was not signed with the private key corresponding to the public key, the `verify_signature` method +will return `false`. + +An event without an `id`, `pubkey`, `sig` is considered invalid and will return `false` when calling `verify_signature`. + +```ruby +other_public_key = Nostr::PublicKey.new('10be96d345ed58d923a734560680f1adfd2b1006c28ac93b8e1b032a9a32c6e9') +event.verify_signature # => false +``` diff --git a/docs/common-use-cases/signing-and-verifying-messages.md b/docs/common-use-cases/signing-and-verifying-messages.md new file mode 100644 index 0000000..53661bc --- /dev/null +++ b/docs/common-use-cases/signing-and-verifying-messages.md @@ -0,0 +1,43 @@ +# Signing and verifying messages + +Signing a message in Nostr proves it was sent by the owner of a specific private key. + +## Signing a message + +To sign a message, you'll need a private key. Here's how to sign a message using a predefined keypair: + +```ruby{9} +require 'nostr' + +private_key = Nostr::PrivateKey.new('67dea2ed018072d675f5415ecfaed7d2597555e202d85b3d65ea4e58d2d92ffa'), +public_key = Nostr::PublicKey.new('7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e'), + +message = 'We did it with security, now we’re going to do it with the economy.' # The message you want to sign + +crypto = Nostr::Crypto.new +signature = crypto.sign_message(message, private_key) +signature # => "d7a0aac1fadcddf1aa2949bedfcdf25ce0c1604e648e55d31431fdacbff8e8256f7c2166d98292f80bc5f79105a0b6e8a89236a47d97cf5d0e7cc1ebf34dea5c" +``` + +## Verifying a signature + +To verify a signature, you need the original message, the public key of the signer, and the signature. + +```ruby +crypto.valid_sig?(message, public_key, signature) # => true +crypto.check_sig!(message, public_key, signature) # => true +``` + +When the message was not signed with the private key corresponding to the public key, the `valid_sig?` method will return `false`. + +```ruby +other_public_key = Nostr::PublicKey.new('10be96d345ed58d923a734560680f1adfd2b1006c28ac93b8e1b032a9a32c6e9') +crypto.valid_sig?(message, public_key, signature) # => false +``` + +And when the message was not signed with the private key corresponding to the public key, the `check_sig!` method will raise an error. + +```ruby +other_public_key = Nostr::PublicKey.new('10be96d345ed58d923a734560680f1adfd2b1006c28ac93b8e1b032a9a32c6e9') +crypto.check_sig!(message, other_public_key, signature) # => Schnorr::InvalidSignatureError: signature verification failed +``` diff --git a/docs/getting-started/overview.md b/docs/getting-started/overview.md index 0cc96ef..bc3a15a 100644 --- a/docs/getting-started/overview.md +++ b/docs/getting-started/overview.md @@ -35,6 +35,7 @@ classDiagram serialize() to_h() sign(private_key) + verify_signature() } class Subscription { id