nostr-rs-relay

My dev fork of nostr-rs-relay
git clone git://jb55.com/nostr-rs-relay
Log | Files | Refs | README | LICENSE

commit 1aa5a5458d0efb16a682868183014db880ea4d38
parent 620e22769977200dc19586310bea30a3a3089608
Author: Greg Heartsfield <scsibug@imap.cc>
Date:   Sat,  1 Jan 2022 09:08:19 -0600

improvement: event signature validation is 100x faster

Switched to latest (git) release of secp256k1, which has more
efficient verification-only context for Schnorr.  Switched to single
pre-instantiated instance of the verifier.

Diffstat:
MCargo.lock | 16++++++++++------
MCargo.toml | 2+-
Msrc/event.rs | 22+++++++++++++++-------
Msrc/main.rs | 6+++---
4 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -67,6 +67,12 @@ dependencies = [ ] [[package]] +name = "bitcoin_hashes" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006cc91e1a1d99819bc5b8214be3555c1f0611b169f527a1fdc54ed1f2b745b0" + +[[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -645,7 +651,7 @@ checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" name = "nostr-rs-relay" version = "0.2.2" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.9.7", "config", "env_logger", "futures", @@ -1031,10 +1037,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "secp256k1" version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +source = "git+https://github.com/rust-bitcoin/rust-secp256k1.git?rev=50034ccb18fdd84904ab3aa6c84a12fcced33209#50034ccb18fdd84904ab3aa6c84a12fcced33209" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.10.0", "rand 0.6.5", "secp256k1-sys", "serde 1.0.131", @@ -1043,8 +1048,7 @@ dependencies = [ [[package]] name = "secp256k1-sys" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "827cb7cce42533829c792fc51b82fbf18b125b45a702ef2c8be77fce65463a7b" +source = "git+https://github.com/rust-bitcoin/rust-secp256k1.git?rev=50034ccb18fdd84904ab3aa6c84a12fcced33209#50034ccb18fdd84904ab3aa6c84a12fcced33209" dependencies = [ "cc", ] diff --git a/Cargo.toml b/Cargo.toml @@ -15,7 +15,7 @@ thiserror = "^1" uuid = { version = "^0.8", features = ["v4"] } config = { version = "0.11", features = ["toml"] } bitcoin_hashes = { version = "^0.9", features = ["serde"] } -secp256k1 = { version = "^0.20", features = ["rand", "rand-std", "serde", "bitcoin_hashes"] } +secp256k1 = {git = "https://github.com/rust-bitcoin/rust-secp256k1.git", rev = "50034ccb18fdd84904ab3aa6c84a12fcced33209", features = ["rand", "rand-std", "serde", "bitcoin_hashes"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" hex = "^0.4" diff --git a/src/event.rs b/src/event.rs @@ -3,14 +3,19 @@ use crate::config; use crate::error::Error::*; use crate::error::Result; use bitcoin_hashes::{sha256, Hash}; +use lazy_static::lazy_static; use log::*; -use secp256k1::{schnorrsig, Secp256k1}; +use secp256k1::{schnorr, Secp256k1, VerifyOnly, XOnlyPublicKey}; use serde::{Deserialize, Deserializer, Serialize}; use serde_json::value::Value; use serde_json::Number; use std::str::FromStr; use std::time::SystemTime; +lazy_static! { + pub static ref SECP: Secp256k1<VerifyOnly> = Secp256k1::verification_only(); +} + /// Event command in network format #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub struct EventCmd { @@ -109,12 +114,15 @@ impl Event { return false; } // * validate the message digest (sig) using the pubkey & computed sha256 message hash. - let secp = Secp256k1::new(); - let sig = schnorrsig::Signature::from_str(&self.sig).unwrap(); - let message = secp256k1::Message::from(digest); - let pubkey = schnorrsig::PublicKey::from_str(&self.pubkey).unwrap(); - let verify = secp.schnorrsig_verify(&sig, &message, &pubkey); - matches!(verify, Ok(())) + let sig = schnorr::Signature::from_str(&self.sig).unwrap(); + if let Ok(msg) = secp256k1::Message::from_slice(digest.as_ref()) { + let pubkey = XOnlyPublicKey::from_str(&self.pubkey).unwrap(); + let verify = SECP.verify_schnorr(&sig, &msg, &pubkey); + matches!(verify, Ok(())) + } else { + warn!("Error converting digest to secp256k1 message"); + false + } } /// Convert event to canonical representation for signing. diff --git a/src/main.rs b/src/main.rs @@ -98,9 +98,9 @@ async fn handle_web_request( } ("/", false) => { // handle request at root with no upgrade header - Ok(Response::new(Body::from(format!( - "This is a Nostr relay.\n" - )))) + Ok(Response::new(Body::from( + "This is a Nostr relay.\n".to_string(), + ))) } (_, _) => { //handle any other url