This commit is contained in:
@@ -34,7 +34,7 @@ jobs:
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ secrets.DOCKER_USERNAME }}/nostr-relay # 你的 Docker Hub 仓库名称,替换为你的用户名
|
||||
images: ${{ secrets.DOCKER_USERNAME }}/nostr_demo # 你的 Docker Hub 仓库名称,替换为你的用户名
|
||||
tags: |
|
||||
type=schedule
|
||||
type=ref,event=branch
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
# Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
Generated
+2376
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -17,7 +17,7 @@ anyhow = "1.0.98"
|
||||
log = "0.4.27"
|
||||
env_logger = "0.11.8"
|
||||
uuid = { version = "1.6.2", features = ["v4"] }
|
||||
sqlx = { version = "0.7.1", features = ["runtime-tokio-rustls", "sqlite"] }
|
||||
sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "sqlite"] }
|
||||
httparse = "1.10.1"
|
||||
toml-cfg = "0.2.0"
|
||||
once_cell = "1.21.3"
|
||||
|
||||
+44
-14
@@ -5,7 +5,7 @@ use hex;
|
||||
use httparse::{EMPTY_HEADER, Request};
|
||||
use log::{Level, debug, error, info, log_enabled};
|
||||
use once_cell::sync::Lazy;
|
||||
use secp256k1::{Message as SecpMessage, PublicKey, Secp256k1, ecdsa::Signature};
|
||||
use secp256k1::{Message as SecpMessage, PublicKey, Secp256k1, ecdsa::Signature, XOnlyPublicKey, schnorr::Signature as SchnorrSignature};
|
||||
use serde::de;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{Value, json};
|
||||
@@ -822,11 +822,14 @@ impl NostrEvent {
|
||||
}
|
||||
|
||||
fn verify(&self) -> bool {
|
||||
debug!("Verifying event: {}", self.id);
|
||||
|
||||
// 1. 验证ID
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(&self.serialize());
|
||||
hasher.update(self.serialize().as_bytes());
|
||||
let result = hasher.finalize();
|
||||
if hex::encode(result) != self.id {
|
||||
debug!("ID verification failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -836,41 +839,62 @@ impl NostrEvent {
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
if self.created_at > now + 900 {
|
||||
debug!("Timestamp verification failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. 验证标签数量
|
||||
if self.tags.len() > MAX_EVENT_TAGS as usize {
|
||||
debug!("Too many tags");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 4. 解析公钥
|
||||
let pubkey_bytes: Vec<u8> = match hex::decode(&self.pubkey) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(_) => return false,
|
||||
Err(e) => {
|
||||
debug!("Failed to decode pubkey: {}", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let public_key: PublicKey = match PublicKey::from_slice(&pubkey_bytes) {
|
||||
Ok(key) => key,
|
||||
Err(_) => return false,
|
||||
let x_only_public_key: XOnlyPublicKey = match pubkey_bytes.try_into().map(|bytes: [u8; 32]| XOnlyPublicKey::from_byte_array(bytes)) {
|
||||
Ok(Ok(key)) => key,
|
||||
_ => {
|
||||
debug!("Failed to parse pubkey");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// 5. 解析签名
|
||||
let sig_bytes: Vec<u8> = match hex::decode(&self.sig) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(_) => return false,
|
||||
Err(_) => {
|
||||
debug!("Failed to decode signature hex");
|
||||
return false;
|
||||
},
|
||||
};
|
||||
let signature: Signature = match Signature::from_compact(&sig_bytes) {
|
||||
let signature: SchnorrSignature = match SchnorrSignature::from_slice(&sig_bytes) {
|
||||
Ok(sig) => sig,
|
||||
Err(_) => return false,
|
||||
Err(_) => {
|
||||
debug!("Failed to parse Schnorr signature");
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
let event_hash: [u8; 32] = match hex::decode(&self.id) {
|
||||
Ok(bytes) => {
|
||||
let mut hash = [0u8; 32];
|
||||
let mut hash = [0u8; 32]; // Note: SHA256 output is 32 bytes
|
||||
if bytes.len() != 32 {
|
||||
debug!("Event ID is not 32 bytes after decoding");
|
||||
return false;
|
||||
}
|
||||
hash.copy_from_slice(&bytes);
|
||||
hash
|
||||
}
|
||||
Err(_) => return false,
|
||||
Err(_) => {
|
||||
debug!("Failed to decode event ID hex");
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
// 6. 创建消息对象
|
||||
@@ -878,9 +902,15 @@ impl NostrEvent {
|
||||
|
||||
// 7. 验证签名
|
||||
let secp = Secp256k1::verification_only();
|
||||
match secp.verify_ecdsa(message, &signature, &public_key) {
|
||||
Ok(_) => true,
|
||||
Err(_) => false,
|
||||
match secp.verify_schnorr(&signature, message.as_ref(), &x_only_public_key) {
|
||||
Ok(_) => {
|
||||
debug!("Event verified: {}", self.id);
|
||||
true
|
||||
},
|
||||
Err(_) => {
|
||||
debug!("Event verification failed: {}", self.id);
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user