Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions crates/buzz-core/src/observer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ pub const OBSERVER_FRAME_CONTROL: &str = "control";
pub const NIP44_MIN_CONTENT_LEN: usize = 132;
/// Maximum NIP-44 v2 ciphertext length.
pub const NIP44_MAX_CONTENT_LEN: usize = 87_472;
/// Maximum observer plaintext JSON size accepted by helpers.
pub const OBSERVER_MAX_PLAINTEXT_LEN: usize = 65_535;
/// Maximum observer plaintext JSON size accepted by the NIP-44 v2 codec.
pub const OBSERVER_MAX_PLAINTEXT_LEN: usize = 65_536 - 128;

/// Errors returned by observer payload encryption/decryption helpers.
#[derive(Debug, Error)]
Expand Down Expand Up @@ -115,6 +115,12 @@ mod tests {
use super::*;
use nostr::{EventBuilder, Kind, Tag};

const NIP44_V2_MAX_PLAINTEXT_LEN: usize = 65_536 - 128;

fn json_string_with_serialized_len(len: usize) -> String {
"x".repeat(len - 2)
}

#[test]
fn observer_payload_round_trips_with_nip44() {
let sender = Keys::generate();
Expand Down Expand Up @@ -156,4 +162,32 @@ mod tests {
Err(ObserverPayloadError::InvalidCiphertextLength(_))
));
}

#[test]
fn observer_payload_accepts_largest_nip44_plaintext() {
let sender = Keys::generate();
let recipient = Keys::generate();
let payload = json_string_with_serialized_len(NIP44_V2_MAX_PLAINTEXT_LEN);

encrypt_observer_payload(&sender, &recipient.public_key(), &payload)
.expect("encrypt maximum-size NIP-44 plaintext");
}

#[test]
fn observer_payload_rejects_plaintext_above_nip44_limit_before_encrypting() {
let sender = Keys::generate();
let recipient = Keys::generate();
let payload = json_string_with_serialized_len(NIP44_V2_MAX_PLAINTEXT_LEN + 1);

let error = encrypt_observer_payload(&sender, &recipient.public_key(), &payload)
.expect_err("reject plaintext above the NIP-44 limit");

match error {
ObserverPayloadError::PlaintextTooLarge { max, got } => {
assert_eq!(max, NIP44_V2_MAX_PLAINTEXT_LEN);
assert_eq!(got, NIP44_V2_MAX_PLAINTEXT_LEN + 1);
}
other => panic!("expected PlaintextTooLarge, got {other:?}"),
}
}
}