mirror of
https://github.com/block/buzz.git
synced 2026-11-05 17:01:35 +00:00
70 lines
2.1 KiB
Rust
70 lines
2.1 KiB
Rust
//! `verify_event()` is CPU-bound (Schnorr). In async contexts call it via
|
|
//! `tokio::task::spawn_blocking` — never directly on an async task.
|
|
|
|
use nostr::{Event, EventId};
|
|
|
|
use crate::error::VerificationError;
|
|
|
|
/// Verifies the event ID hash and Schnorr signature.
|
|
///
|
|
/// CPU-bound — call via `tokio::task::spawn_blocking` in async contexts.
|
|
pub fn verify_event(event: &Event) -> Result<(), VerificationError> {
|
|
if !event.verify_id() {
|
|
let computed = EventId::new(
|
|
&event.pubkey,
|
|
&event.created_at,
|
|
&event.kind,
|
|
event.tags.as_slice(),
|
|
&event.content,
|
|
)
|
|
.to_hex();
|
|
return Err(VerificationError::InvalidId {
|
|
computed,
|
|
got: event.id.to_hex(),
|
|
});
|
|
}
|
|
|
|
if !event.verify_signature() {
|
|
return Err(VerificationError::InvalidSignature);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use nostr::{EventBuilder, JsonUtil, Keys, Kind};
|
|
|
|
fn make_valid_event() -> Event {
|
|
let keys = Keys::generate();
|
|
EventBuilder::new(Kind::TextNote, "test content", [])
|
|
.sign_with_keys(&keys)
|
|
.expect("sign")
|
|
}
|
|
|
|
#[test]
|
|
fn rejects_tampered_id() {
|
|
let keys = Keys::generate();
|
|
let event = EventBuilder::new(Kind::TextNote, "original", [])
|
|
.sign_with_keys(&keys)
|
|
.expect("sign");
|
|
let mut json: serde_json::Value = serde_json::from_str(&event.as_json()).expect("parse");
|
|
json["content"] = serde_json::Value::String("tampered".to_string());
|
|
let tampered = Event::from_json(json.to_string()).expect("parse");
|
|
assert!(matches!(
|
|
verify_event(&tampered),
|
|
Err(VerificationError::InvalidId { .. })
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn rejects_tampered_signature() {
|
|
let event = make_valid_event();
|
|
let mut json: serde_json::Value = serde_json::from_str(&event.as_json()).expect("parse");
|
|
json["sig"] = serde_json::Value::String("0".repeat(128));
|
|
let tampered = Event::from_json(json.to_string()).expect("parse");
|
|
assert!(verify_event(&tampered).is_err());
|
|
}
|
|
}
|