wip: validate delegation sig

This commit is contained in:
Greg Heartsfield 2022-10-15 17:13:34 -05:00
parent 66cca169f1
commit eea37fbf5c
2 changed files with 48 additions and 16 deletions

View File

@ -1,18 +1,13 @@
//! Event parsing and validation
use crate::error::Error;
use crate::error::Result;
//use crate::utils::unix_time;
//use bitcoin_hashes::{sha256, Hash};
use bitcoin_hashes::{sha256, Hash};
use lazy_static::lazy_static;
use regex::Regex;
//use secp256k1::{schnorr, Secp256k1, VerifyOnly, XOnlyPublicKey};
use secp256k1::{schnorr, Secp256k1, VerifyOnly, XOnlyPublicKey};
use serde::{Deserialize, Serialize};
//use serde_json::value::Value;
//use serde_json::Number;
//use std::collections::HashMap;
//use std::collections::HashSet;
use std::str::FromStr;
//use tracing::{debug, info};
use tracing::{debug, info};
// This handles everything related to delegation, in particular the
// condition/rune parsing and logic.
@ -38,6 +33,11 @@ use std::str::FromStr;
// condition string. We will then map that with a deserializer that
// maps to a ConditionQuery.
lazy_static! {
/// Secp256k1 verification instance.
pub static ref SECP: Secp256k1<VerifyOnly> = Secp256k1::verification_only();
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
pub enum Field {
Kind,
@ -86,12 +86,34 @@ pub struct ConditionQuery {
pub(crate) conditions: Vec<Condition>,
}
/// Parsed delegation statement
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
pub struct Delegation {
pub(crate) pubkey: String,
pub(crate) condition_query: ConditionQuery,
pub(crate) signature: String,
// Verify that the delegator approved the delegation; return a ConditionQuery if so.
pub fn validate_delegation(
delegator: &str,
delegatee: &str,
cond_query: &str,
sigstr: &str,
) -> Option<ConditionQuery> {
// form the token
let tok = format!("nostr:delegation:{}:{}", delegatee, cond_query);
// form SHA256 hash
let digest: sha256::Hash = sha256::Hash::hash(tok.as_bytes());
let sig = schnorr::Signature::from_str(sigstr).unwrap();
if let Ok(msg) = secp256k1::Message::from_slice(digest.as_ref()) {
if let Ok(pubkey) = XOnlyPublicKey::from_str(delegator) {
let verify = SECP.verify_schnorr(&sig, &msg, &pubkey);
if verify.is_ok() {
Some(ConditionQuery { conditions: vec![] })
} else {
None
}
} else {
debug!("client sent malformed pubkey");
None
}
} else {
info!("error converting digest to secp256k1 message");
None
}
}
/// Parsed delegation condition

View File

@ -1,4 +1,5 @@
//! Event parsing and validation
use crate::delegation::validate_delegation;
use crate::error::Error::*;
use crate::error::Result;
use crate::nip05;
@ -112,10 +113,19 @@ impl Event {
// is this event delegated (properly)?
// does the signature match, and are conditions valid?
pub fn is_delegated(&self) -> bool {
// if so, return an alternate author for the event
pub fn delegated_author(&self) -> Option<String> {
// is there a delegation tag?
let _delegation_tag = self.tag_values_by_name("delegation");
let delegation_tag = self.tag_values_by_name("delegation");
// delegation tags should have exactly 3 elements after the name (pubkey, condition, sig)
// the event is signed by the delagatee
let delegatee = &self.pubkey;
// the delegation tag references the claimed delagator
let delegator = delegation_tag.get(0)?;
let querystr = delegation_tag.get(1)?;
let sig = delegation_tag.get(2)?;
// pass into the validate_delegation
validate_delegation(delegator, delegatee, querystr, sig);
// try to construct a delegation object (
todo!();
}