1use std::collections::VecDeque;
7
8use buffa::{Message, MessageField};
9
10use hmac::{HmacReset, KeyInit, Mac};
11use sha2::Sha256;
12
13use crate::protocol::counter_lease::CounterLease;
14use crate::protocol::crypto::hmac_sha256;
15use crate::protocol::record_components::{
16 SenderKeyRecordComponents, sender_state_components_from_structure,
17 sender_state_structure_from_components,
18};
19use crate::protocol::stores::{
20 SenderKeyRecordStructure, SenderKeyStateStructure, sender_key_state_structure,
21};
22use crate::protocol::{PrivateKey, PublicKey, SignalProtocolError, consts};
23use subtle::ConstantTimeEq;
24
25#[derive(Debug)]
27pub struct InvalidSenderKeySessionError(&'static str);
28
29impl std::fmt::Display for InvalidSenderKeySessionError {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 self.0.fmt(f)
32 }
33}
34
35#[derive(Debug, Clone)]
36pub struct SenderMessageKey {
37 iteration: u32,
38 iv: [u8; 16],
39 cipher_key: [u8; 32],
40 seed: [u8; 32],
41}
42
43impl SenderMessageKey {
44 pub fn new(iteration: u32, seed: [u8; 32]) -> Self {
45 let mut derived = [0u8; 48];
46 hkdf::Hkdf::<Sha256>::new(None, &seed)
47 .expand(b"WhisperGroup", &mut derived)
48 .expect("valid output length");
49 Self {
50 iteration,
51 seed,
52 iv: derived[0..16].try_into().expect("correct iv length"),
53 cipher_key: derived[16..48]
54 .try_into()
55 .expect("correct cipher_key length"),
56 }
57 }
58
59 pub fn iteration(&self) -> u32 {
60 self.iteration
61 }
62
63 pub fn iv(&self) -> &[u8] {
64 &self.iv
65 }
66
67 pub fn cipher_key(&self) -> &[u8] {
68 &self.cipher_key
69 }
70}
71
72#[derive(Debug, Clone, Copy)]
78struct StoredMessageKey {
79 iteration: u32,
80 seed: [u8; 32],
81}
82
83impl StoredMessageKey {
84 fn from_protobuf(smk: &sender_key_state_structure::SenderMessageKey) -> Self {
85 Self {
87 iteration: smk.iteration.unwrap_or_default(),
88 seed: smk
89 .seed
90 .as_deref()
91 .and_then(|b| b.try_into().ok())
92 .unwrap_or_default(),
93 }
94 }
95
96 fn as_protobuf(&self) -> sender_key_state_structure::SenderMessageKey {
97 sender_key_state_structure::SenderMessageKey {
98 iteration: Some(self.iteration),
99 seed: Some(bytes::Bytes::copy_from_slice(&self.seed)),
100 }
101 }
102}
103
104fn seed_to_array(seed: Option<&bytes::Bytes>) -> Result<[u8; 32], SignalProtocolError> {
105 let Some(seed) = seed else {
106 return Err(SignalProtocolError::InvalidProtobufEncoding);
107 };
108 seed.as_ref()
109 .try_into()
110 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)
111}
112
113#[derive(Debug, Clone, Copy)]
114pub struct SenderChainKey {
115 iteration: u32,
116 chain_key: [u8; 32],
117}
118
119impl SenderChainKey {
120 const MESSAGE_KEY_SEED: u8 = 0x01;
121 const CHAIN_KEY_SEED: u8 = 0x02;
122
123 pub(crate) fn new(iteration: u32, chain_key: [u8; 32]) -> Self {
124 Self {
125 iteration,
126 chain_key,
127 }
128 }
129
130 pub fn iteration(&self) -> u32 {
131 self.iteration
132 }
133
134 pub fn seed(&self) -> &[u8; 32] {
135 &self.chain_key
136 }
137
138 pub fn next(&self) -> Result<SenderChainKey, SignalProtocolError> {
139 let new_iteration = self.iteration.checked_add(1).ok_or_else(|| {
140 SignalProtocolError::InvalidState(
141 "sender_chain_key_next",
142 "Sender chain is too long".into(),
143 )
144 })?;
145
146 Ok(SenderChainKey::new(
147 new_iteration,
148 self.get_derivative(Self::CHAIN_KEY_SEED),
149 ))
150 }
151
152 pub fn sender_message_key(&self) -> SenderMessageKey {
153 SenderMessageKey::new(self.iteration, self.get_derivative(Self::MESSAGE_KEY_SEED))
154 }
155
156 #[inline]
158 pub fn step_with_message_key(&self) -> Result<(SenderMessageKey, Self), SignalProtocolError> {
159 let new_iteration = self.iteration.checked_add(1).ok_or_else(|| {
160 SignalProtocolError::InvalidState(
161 "sender_chain_key_step",
162 "Sender chain is too long".into(),
163 )
164 })?;
165
166 let mut hmac = HmacReset::<Sha256>::new_from_slice(&self.chain_key)
167 .expect("HMAC-SHA256 should accept any size key");
168
169 hmac.update(&[Self::MESSAGE_KEY_SEED]);
170 let message_key_seed: [u8; 32] = hmac.finalize_reset().into_bytes().into();
171
172 hmac.update(&[Self::CHAIN_KEY_SEED]);
173 let next_chain_key: [u8; 32] = hmac.finalize().into_bytes().into();
174
175 let message_key = SenderMessageKey::new(self.iteration, message_key_seed);
176 let next_chain = Self {
177 iteration: new_iteration,
178 chain_key: next_chain_key,
179 };
180
181 Ok((message_key, next_chain))
182 }
183
184 #[inline]
185 fn get_derivative(&self, label: u8) -> [u8; 32] {
186 let label = [label];
187 hmac_sha256(&self.chain_key, &label)
188 }
189
190 pub(crate) fn as_protobuf(&self) -> sender_key_state_structure::SenderChainKey {
191 use bytes::Bytes;
192 sender_key_state_structure::SenderChainKey {
193 iteration: Some(self.iteration),
194 seed: Some(Bytes::copy_from_slice(&self.chain_key)),
195 }
196 }
197}
198
199#[derive(Clone)]
200pub struct SenderKeyState {
201 state: SenderKeyStateStructure,
202 message_keys: std::sync::Arc<Vec<StoredMessageKey>>,
212 sender_chain: Option<SenderChainKey>,
220 signing_key_memo: std::sync::OnceLock<PrivateKey>,
235 verifying_key_memo: std::sync::OnceLock<crate::core::curve::PreparedVerifyingKey>,
239}
240
241impl std::fmt::Debug for SenderKeyState {
245 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
246 f.debug_struct("SenderKeyState")
247 .field("chain_id", &self.chain_id())
248 .field(
249 "chain_iteration",
250 &self.sender_chain_key().map(|c| c.iteration()),
251 )
252 .field("message_keys", &self.message_keys.len())
253 .field("signing_key", &"<redacted>")
254 .finish_non_exhaustive()
255 }
256}
257
258impl SenderKeyState {
259 pub fn new(
260 _message_version: u8,
261 chain_id: u32,
262 iteration: u32,
263 chain_key: &[u8],
264 signature_key: PublicKey,
265 signature_private_key: Option<PrivateKey>,
266 ) -> Result<SenderKeyState, SignalProtocolError> {
267 use bytes::Bytes;
268 let chain_key_arr: [u8; 32] = chain_key
269 .try_into()
270 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
271 let sender_chain = Some(SenderChainKey::new(iteration, chain_key_arr));
272 let state = SenderKeyStateStructure {
273 sender_key_id: Some(chain_id),
274 sender_chain_key: MessageField::none(),
277 sender_signing_key: MessageField::some(sender_key_state_structure::SenderSigningKey {
278 public: Some(Bytes::copy_from_slice(&signature_key.serialize())),
279 private: signature_private_key
280 .as_ref()
281 .map(|k| Bytes::copy_from_slice(k.serialize().as_ref())),
282 }),
283 sender_message_keys: vec![],
284 };
285
286 let signing_key_memo = std::sync::OnceLock::new();
287 if let Some(key) = signature_private_key {
288 key.precompute_signing_cache();
289 let _ = signing_key_memo.set(key);
290 }
291 let verifying_key_memo = std::sync::OnceLock::new();
292 if signing_key_memo.get().is_none() {
293 let verifier = crate::core::curve::PreparedVerifyingKey::new(&signature_key);
297 verifier.precompute();
298 let _ = verifying_key_memo.set(verifier);
299 }
300 Ok(Self {
301 state,
302 message_keys: std::sync::Arc::new(Vec::new()),
303 sender_chain,
304 signing_key_memo,
305 verifying_key_memo,
306 })
307 }
308
309 pub(crate) fn from_protobuf(mut state: SenderKeyStateStructure) -> Self {
310 let message_keys = std::sync::Arc::new(
313 std::mem::take(&mut state.sender_message_keys)
314 .iter()
315 .map(StoredMessageKey::from_protobuf)
316 .collect::<Vec<_>>(),
317 );
318 let sender_chain = state.sender_chain_key.take().and_then(|sc| {
321 let seed: [u8; 32] = sc.seed.as_deref()?.try_into().ok()?;
322 Some(SenderChainKey::new(sc.iteration.unwrap_or_default(), seed))
323 });
324 Self {
325 state,
326 message_keys,
327 sender_chain,
328 signing_key_memo: std::sync::OnceLock::new(),
329 verifying_key_memo: std::sync::OnceLock::new(),
330 }
331 }
332
333 pub fn message_version(&self) -> u32 {
334 3
335 }
336
337 pub fn chain_id(&self) -> u32 {
338 self.state.sender_key_id.unwrap_or_default()
339 }
340
341 pub fn sender_chain_key(&self) -> Option<SenderChainKey> {
342 self.sender_chain
343 }
344
345 pub fn set_sender_chain_key(&mut self, chain_key: SenderChainKey) {
346 self.sender_chain = Some(chain_key);
347 }
348
349 pub(crate) fn fast_forward_sender_chain(
355 &mut self,
356 target: u32,
357 ) -> Result<(), SignalProtocolError> {
358 let Some(mut chain_key) = self.sender_chain_key() else {
359 return Ok(());
360 };
361 if target.saturating_sub(chain_key.iteration()) > consts::MAX_RESERVATION_FAST_FORWARD {
362 return Err(SignalProtocolError::InvalidState(
363 "fast_forward_sender_chain",
364 "reserved sender-key iteration implausibly far ahead".into(),
365 ));
366 }
367 if chain_key.iteration() >= target {
368 return Ok(());
369 }
370 while chain_key.iteration() < target {
371 chain_key = chain_key.next()?;
372 }
373 self.set_sender_chain_key(chain_key);
374 Ok(())
375 }
376
377 pub fn signing_key_public(&self) -> Result<PublicKey, InvalidSenderKeySessionError> {
378 if let Some(signing_key) = self.state.sender_signing_key.as_option() {
379 let public = signing_key
380 .public
381 .as_ref()
382 .ok_or(InvalidSenderKeySessionError("missing public key bytes"))?;
383 PublicKey::try_from(&public[..])
384 .map_err(|_| InvalidSenderKeySessionError("invalid public signing key"))
385 } else {
386 Err(InvalidSenderKeySessionError("missing signing key"))
387 }
388 }
389
390 pub fn signing_key_verifier(
393 &self,
394 ) -> Result<&crate::core::curve::PreparedVerifyingKey, InvalidSenderKeySessionError> {
395 if let Some(verifier) = self.verifying_key_memo.get() {
396 return Ok(verifier);
397 }
398 let verifier = crate::core::curve::PreparedVerifyingKey::new(&self.signing_key_public()?);
399 let _ = self.verifying_key_memo.set(verifier);
401 Ok(self
402 .verifying_key_memo
403 .get()
404 .expect("set on the line above"))
405 }
406
407 pub fn prewarm_signing_key(&self, key: PrivateKey) -> Result<(), InvalidSenderKeySessionError> {
426 if !bool::from(self.signing_key_bytes()?.ct_eq(key.serialize())) {
427 return Err(InvalidSenderKeySessionError(
428 "prewarmed signing key belongs to another state",
429 ));
430 }
431 if self.signing_key_memo.get().is_some() {
435 return Ok(());
436 }
437 key.precompute_signing_cache();
441 let _ = self.signing_key_memo.set(key);
442 Ok(())
443 }
444
445 pub fn prewarm_verifying_key(
453 &self,
454 verifier: crate::core::curve::PreparedVerifyingKey,
455 ) -> Result<(), InvalidSenderKeySessionError> {
456 if !verifier.is_for(&self.signing_key_public()?) {
457 return Err(InvalidSenderKeySessionError(
458 "prewarmed verifier belongs to another state",
459 ));
460 }
461 let _ = self.verifying_key_memo.set(verifier);
467 if let Some(retained) = self.verifying_key_memo.get() {
468 retained.precompute();
469 }
470 Ok(())
471 }
472
473 fn signing_key_bytes(&self) -> Result<[u8; 32], InvalidSenderKeySessionError> {
476 let signing_key = self
477 .state
478 .sender_signing_key
479 .as_option()
480 .ok_or(InvalidSenderKeySessionError("missing signing key"))?;
481 let private = signing_key
482 .private
483 .as_ref()
484 .ok_or(InvalidSenderKeySessionError("missing private key bytes"))?;
485 Ok(*PrivateKey::deserialize(private)
486 .map_err(|_| InvalidSenderKeySessionError("invalid private signing key"))?
487 .serialize())
488 }
489
490 pub fn signing_key_private(&self) -> Result<PrivateKey, InvalidSenderKeySessionError> {
491 if let Some(key) = self.signing_key_memo.get() {
492 return Ok(key.clone());
493 }
494 if let Some(signing_key) = self.state.sender_signing_key.as_option() {
495 let private = signing_key
496 .private
497 .as_ref()
498 .ok_or(InvalidSenderKeySessionError("missing private key bytes"))?;
499 let key = PrivateKey::deserialize(private)
500 .map_err(|_| InvalidSenderKeySessionError("invalid private signing key"))?;
501 key.precompute_signing_cache();
505 let _ = self.signing_key_memo.set(key.clone());
506 Ok(key)
507 } else {
508 Err(InvalidSenderKeySessionError("missing signing key"))
509 }
510 }
511
512 #[cfg(test)]
514 pub(crate) fn signing_key_memo_initialized(&self) -> bool {
515 self.signing_key_memo.get().is_some()
516 }
517
518 pub(crate) fn as_protobuf(&self) -> SenderKeyStateStructure {
519 debug_assert!(
520 self.state.sender_message_keys.is_empty()
521 && self.state.sender_chain_key.as_option().is_none(),
522 "backlog and chain key must live only in their Copy/Arc fields; the protobuf copies stay empty"
523 );
524 let mut state = self.state.clone();
525 state.sender_message_keys = self
526 .message_keys
527 .iter()
528 .map(StoredMessageKey::as_protobuf)
529 .collect();
530 state.sender_chain_key = self
531 .sender_chain
532 .as_ref()
533 .map_or_else(MessageField::none, |c| MessageField::some(c.as_protobuf()));
534 state
535 }
536
537 fn into_protobuf(mut self) -> SenderKeyStateStructure {
538 debug_assert!(
539 self.state.sender_message_keys.is_empty()
540 && self.state.sender_chain_key.as_option().is_none(),
541 "backlog and chain key must have a single in-memory owner"
542 );
543 let message_keys = std::sync::Arc::try_unwrap(self.message_keys)
544 .unwrap_or_else(|shared| shared.as_ref().clone());
545 self.state.sender_message_keys = message_keys
546 .iter()
547 .map(StoredMessageKey::as_protobuf)
548 .collect();
549 self.state.sender_chain_key = self
550 .sender_chain
551 .as_ref()
552 .map_or_else(MessageField::none, |chain| {
553 MessageField::some(chain.as_protobuf())
554 });
555 self.state
556 }
557
558 pub fn add_sender_message_key(&mut self, sender_message_key: &SenderMessageKey) {
559 let keys = std::sync::Arc::make_mut(&mut self.message_keys);
560 keys.push(StoredMessageKey {
561 iteration: sender_message_key.iteration,
562 seed: sender_message_key.seed,
563 });
564 let len = keys.len();
567 if len > consts::MAX_MESSAGE_KEYS + consts::MESSAGE_KEY_PRUNE_THRESHOLD {
568 let excess = len - consts::MAX_MESSAGE_KEYS;
569 keys.drain(..excess);
570 }
571 }
572
573 pub(crate) fn remove_sender_message_key(&mut self, iteration: u32) -> Option<SenderMessageKey> {
574 let index = self
577 .message_keys
578 .iter()
579 .position(|x| x.iteration == iteration)?;
580 let smk = std::sync::Arc::make_mut(&mut self.message_keys).remove(index);
581 Some(SenderMessageKey::new(smk.iteration, smk.seed))
582 }
583}
584
585#[derive(Debug, Clone)]
586pub struct SenderKeyRecord {
587 states: VecDeque<SenderKeyState>,
588 lease: CounterLease,
598}
599
600const RESERVED_ITERATION_FIELD: u32 = super::local_field::COUNTER_RESERVATION_FIELD;
605
606impl SenderKeyRecord {
607 pub fn new_empty() -> Self {
608 Self {
609 states: VecDeque::with_capacity(consts::MAX_SENDER_KEY_STATES),
610 lease: CounterLease::default(),
611 }
612 }
613
614 pub fn from_components(value: SenderKeyRecordComponents) -> Result<Self, SignalProtocolError> {
621 let states = value
622 .states
623 .into_iter()
624 .take(consts::MAX_SENDER_KEY_STATES)
625 .map(sender_state_structure_from_components)
626 .map(|state| state.map(SenderKeyState::from_protobuf))
627 .collect::<Result<VecDeque<_>, _>>()?;
628
629 Ok(Self {
630 states,
631 lease: CounterLease::default(),
632 })
633 }
634
635 pub fn into_components(mut self) -> Result<SenderKeyRecordComponents, SignalProtocolError> {
641 let reserved_iteration = self.lease.ceiling();
642 if reserved_iteration > 0
643 && let Some(state) = self.states.front_mut()
644 {
645 state.fast_forward_sender_chain(reserved_iteration)?;
646 }
647 let states = self
648 .states
649 .into_iter()
650 .map(SenderKeyState::into_protobuf)
651 .map(sender_state_components_from_structure)
652 .collect::<Result<Vec<_>, _>>()?;
653 Ok(SenderKeyRecordComponents { states })
654 }
655
656 pub fn is_empty(&self) -> bool {
657 self.states.is_empty()
658 }
659
660 pub fn reserved_iteration(&self) -> u32 {
663 self.lease.ceiling()
664 }
665
666 pub fn waive_counter_lease(&mut self) -> Result<(), SignalProtocolError> {
672 let ceiling = self.lease.ceiling();
676 if ceiling > 0
677 && let Some(state) = self.states.front_mut()
678 {
679 state.fast_forward_sender_chain(ceiling)?;
680 }
681 self.lease.waive();
682 Ok(())
683 }
684
685 pub fn reserve_iterations(&mut self, spent_iteration: u32) {
690 self.lease.reserve(spent_iteration);
691 }
692
693 pub fn deserialize(buf: &[u8]) -> Result<SenderKeyRecord, SignalProtocolError> {
694 Self::deserialize_inner(buf, None)
695 }
696
697 #[doc(hidden)]
699 pub fn deserialize_for_store(
700 buf: &[u8],
701 incarnation: &[u8; 16],
702 ) -> Result<SenderKeyRecord, SignalProtocolError> {
703 Self::deserialize_inner(buf, Some(incarnation))
704 }
705
706 fn deserialize_inner(
707 buf: &[u8],
708 incarnation: Option<&[u8; 16]>,
709 ) -> Result<SenderKeyRecord, SignalProtocolError> {
710 let skr = waproto::codec::sender_key_record_decode(buf)
711 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
712
713 let mut states = VecDeque::with_capacity(
714 skr.sender_key_states
715 .len()
716 .min(consts::MAX_SENDER_KEY_STATES),
717 );
718 for state in skr
719 .sender_key_states
720 .into_iter()
721 .take(consts::MAX_SENDER_KEY_STATES)
722 {
723 if let Some(sender_chain) = state.sender_chain_key.as_option() {
725 let _ = seed_to_array(sender_chain.seed.as_ref())?;
726 }
727 for smk in &state.sender_message_keys {
728 let _ = seed_to_array(smk.seed.as_ref())?;
729 }
730 states.push_back(SenderKeyState::from_protobuf(state));
731 }
732
733 let local_fields =
734 super::local_field::decode_local_record_fields(buf, RESERVED_ITERATION_FIELD, || {
735 SignalProtocolError::InvalidProtobufEncoding
736 })?;
737 let reserved_iteration = local_fields.reservation;
738 let trusted_reload =
739 incarnation.is_some_and(|current| local_fields.incarnation == Some(*current));
740
741 if !trusted_reload
743 && reserved_iteration > 0
744 && let Some(state) = states.front_mut()
745 {
746 state.fast_forward_sender_chain(reserved_iteration)?;
747 }
748
749 Ok(Self {
750 states,
751 lease: CounterLease::from_persisted_ceiling(reserved_iteration),
752 })
753 }
754
755 pub fn mark_wire_gated(&mut self) {
758 self.lease.set_pending_flush(true);
759 }
760
761 pub fn is_wire_gated(&self) -> bool {
762 self.lease.is_pending_flush()
763 }
764
765 pub fn clear_wire_gated(&mut self) {
766 self.lease.set_pending_flush(false);
767 }
768
769 pub fn sender_key_state(&self) -> Result<&SenderKeyState, InvalidSenderKeySessionError> {
770 if !self.states.is_empty() {
771 return Ok(&self.states[0]);
772 }
773 Err(InvalidSenderKeySessionError("empty sender key state"))
774 }
775
776 pub fn sender_key_state_mut(
777 &mut self,
778 ) -> Result<&mut SenderKeyState, InvalidSenderKeySessionError> {
779 if !self.states.is_empty() {
780 return Ok(&mut self.states[0]);
781 }
782 Err(InvalidSenderKeySessionError("empty sender key state"))
783 }
784
785 pub(crate) fn sender_key_state_for_chain_id(
786 &mut self,
787 chain_id: u32,
788 ) -> Option<&mut SenderKeyState> {
789 for i in 0..self.states.len() {
790 if self.states[i].chain_id() == chain_id {
791 return Some(&mut self.states[i]);
792 }
793 }
794 None
795 }
796
797 pub(crate) fn chain_ids_for_logging(&self) -> impl ExactSizeIterator<Item = u32> + '_ {
798 self.states.iter().map(|state| state.chain_id())
799 }
800
801 pub fn add_sender_key_state(
802 &mut self,
803 message_version: u8,
804 chain_id: u32,
805 iteration: u32,
806 chain_key: &[u8],
807 signature_key: PublicKey,
808 signature_private_key: Option<PrivateKey>,
809 ) -> Result<(), SignalProtocolError> {
810 let existing_state = self.remove_state(chain_id, signature_key);
811
812 if self.remove_states_with_chain_id(chain_id) > 0 {
813 log::warn!(
814 "Removed a matching chain_id ({chain_id}) found with a different public key"
815 );
816 }
817
818 let state = match existing_state {
819 None => SenderKeyState::new(
820 message_version,
821 chain_id,
822 iteration,
823 chain_key,
824 signature_key,
825 signature_private_key,
826 )?,
827 Some(state) => state,
828 };
829
830 while self.states.len() >= consts::MAX_SENDER_KEY_STATES {
831 self.states.pop_back();
832 }
833
834 self.states.push_front(state);
835 self.lease.clear_reservation();
845 Ok(())
846 }
847
848 fn remove_state(&mut self, chain_id: u32, signature_key: PublicKey) -> Option<SenderKeyState> {
852 let (index, _state) = self.states.iter().enumerate().find(|(_, state)| {
853 state.chain_id() == chain_id && state.signing_key_public().ok() == Some(signature_key)
854 })?;
855
856 self.states.remove(index)
857 }
858
859 fn remove_states_with_chain_id(&mut self, chain_id: u32) -> usize {
863 let initial_length = self.states.len();
864 self.states.retain(|state| state.chain_id() != chain_id);
865 initial_length - self.states.len()
866 }
867
868 pub(crate) fn as_protobuf(&self) -> SenderKeyRecordStructure {
869 let mut states = Vec::with_capacity(self.states.len());
870 for state in &self.states {
871 states.push(state.as_protobuf());
872 }
873
874 SenderKeyRecordStructure {
875 sender_key_states: states,
876 }
877 }
878
879 pub fn serialize(&self) -> Result<Vec<u8>, SignalProtocolError> {
880 self.serialize_inner(None)
881 }
882
883 #[doc(hidden)]
885 pub fn serialize_for_store(
886 &self,
887 incarnation: &[u8; 16],
888 ) -> Result<Vec<u8>, SignalProtocolError> {
889 self.serialize_inner(Some(incarnation))
890 }
891
892 fn serialize_inner(
893 &self,
894 incarnation: Option<&[u8; 16]>,
895 ) -> Result<Vec<u8>, SignalProtocolError> {
896 use buffa::encoding::{Tag, WireType, encode_varint, varint_len};
897
898 let mut buf = waproto::codec::sender_key_record_to_vec(&self.as_protobuf());
899 let reserved_iteration = self.lease.ceiling();
900 let incarnation = incarnation.filter(|_| reserved_iteration > 0);
901 let reservation_len = if reserved_iteration > 0 {
902 2 + varint_len(reserved_iteration as u64)
903 } else {
904 0
905 };
906 let incarnation_len = incarnation
907 .map(|_| super::local_field::STORE_INCARNATION_ENCODED_LEN)
908 .unwrap_or(0);
909 buf.reserve(reservation_len + incarnation_len);
910 if reserved_iteration > 0 {
914 Tag::new(RESERVED_ITERATION_FIELD, WireType::Varint).encode(&mut buf);
915 encode_varint(reserved_iteration as u64, &mut buf);
916 }
917 if let Some(incarnation) = incarnation {
918 super::local_field::encode_store_incarnation(&mut buf, incarnation);
919 }
920 Ok(buf)
921 }
922
923 pub fn estimated_size(&self) -> usize {
928 let mut cache = buffa::SizeCache::new();
929 self.states
930 .iter()
931 .map(|s| {
932 s.state.compute_size(&mut cache) as usize
933 + s.message_keys.len() * size_of::<StoredMessageKey>()
934 + s.sender_chain.map_or(0, |_| size_of::<SenderChainKey>())
935 })
936 .sum()
937 }
938}
939
940#[cfg(test)]
941#[allow(clippy::disallowed_methods)]
942mod tests {
943 use super::*;
944 use crate::protocol::KeyPair;
945
946 #[test]
949 fn a_prewarmed_state_signs_and_verifies_exactly_like_a_cold_one() {
950 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
951 let signing = KeyPair::generate(&mut rng);
952 let private_bytes = *signing.private_key.serialize();
953 let fresh = || {
954 let key = PrivateKey::deserialize(&private_bytes).expect("key");
955 let state = SenderKeyState::new(3, 1, 0, &[7u8; 32], signing.public_key, Some(key))
956 .expect("valid inputs");
957 SenderKeyState::from_protobuf(state.as_protobuf())
958 };
959
960 let lazy = fresh();
962 assert!(!lazy.signing_key_memo_initialized());
963
964 let prewarmed = fresh();
966 let derived = PrivateKey::deserialize(&private_bytes).expect("key");
967 derived.precompute_signing_cache();
968 prewarmed
969 .prewarm_signing_key(derived)
970 .expect("own key is accepted");
971 assert!(prewarmed.signing_key_memo_initialized());
972 prewarmed
973 .prewarm_verifying_key(crate::core::curve::PreparedVerifyingKey::new(
974 &signing.public_key,
975 ))
976 .expect("own verifier is accepted");
977
978 let message = b"skmsg";
979 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
980 let from_lazy = lazy
981 .signing_key_private()
982 .expect("lazy key")
983 .calculate_signature(message, &mut rng)
984 .expect("sign");
985 let from_prewarmed = prewarmed
986 .signing_key_private()
987 .expect("prewarmed key")
988 .calculate_signature(message, &mut rng)
989 .expect("sign");
990
991 for signature in [&from_lazy, &from_prewarmed] {
993 assert!(
994 lazy.signing_key_verifier()
995 .expect("lazy verifier")
996 .verify_signature(message, signature)
997 );
998 assert!(
999 prewarmed
1000 .signing_key_verifier()
1001 .expect("prewarmed verifier")
1002 .verify_signature(message, signature)
1003 );
1004 }
1005 }
1006
1007 #[test]
1012 fn prewarming_with_cold_material_still_leaves_the_memos_warm() {
1013 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1014 let signing = KeyPair::generate(&mut rng);
1015 let private_bytes = *signing.private_key.serialize();
1016 let state = SenderKeyState::new(
1017 3,
1018 1,
1019 0,
1020 &[7u8; 32],
1021 signing.public_key,
1022 Some(PrivateKey::deserialize(&private_bytes).expect("key")),
1023 )
1024 .expect("valid inputs");
1025 let state = SenderKeyState::from_protobuf(state.as_protobuf());
1026
1027 let cold = PrivateKey::deserialize(&private_bytes).expect("key");
1030 assert!(!cold.has_warm_signing_cache());
1031 state.prewarm_signing_key(cold).expect("own key");
1032
1033 assert!(
1034 state
1035 .signing_key_private()
1036 .expect("memo key")
1037 .has_warm_signing_cache(),
1038 "a clone taken from the memo must carry the warm cache"
1039 );
1040
1041 let cold = crate::core::curve::PreparedVerifyingKey::new(&signing.public_key);
1044 assert!(!cold.is_precomputed());
1045 state.prewarm_verifying_key(cold).expect("own verifier");
1046 assert!(
1047 state
1048 .signing_key_verifier()
1049 .expect("memo verifier")
1050 .is_precomputed(),
1051 "the memoized verifier must have its entries derived"
1052 );
1053 }
1054
1055 #[test]
1058 fn prewarming_with_another_states_material_is_refused() {
1059 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1060 let mine = KeyPair::generate(&mut rng);
1061 let theirs = KeyPair::generate(&mut rng);
1062 let mine_bytes = *mine.private_key.serialize();
1063 let state = SenderKeyState::new(
1064 3,
1065 1,
1066 0,
1067 &[7u8; 32],
1068 mine.public_key,
1069 Some(PrivateKey::deserialize(&mine_bytes).expect("key")),
1070 )
1071 .expect("valid inputs");
1072 let state = SenderKeyState::from_protobuf(state.as_protobuf());
1073
1074 assert!(state.prewarm_signing_key(theirs.private_key).is_err());
1075 assert!(
1076 state
1077 .prewarm_verifying_key(crate::core::curve::PreparedVerifyingKey::new(
1078 &theirs.public_key
1079 ))
1080 .is_err()
1081 );
1082
1083 assert!(!state.signing_key_memo_initialized());
1085 assert_eq!(
1086 *state.signing_key_private().expect("own key").serialize(),
1087 mine_bytes
1088 );
1089 assert!(
1090 state
1091 .signing_key_verifier()
1092 .expect("own verifier")
1093 .is_for(&mine.public_key)
1094 );
1095 }
1096
1097 #[test]
1100 fn prewarming_an_already_warm_state_is_inert() {
1101 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1102 let signing = KeyPair::generate(&mut rng);
1103 let private_bytes = *signing.private_key.serialize();
1104 let state = SenderKeyState::new(
1105 3,
1106 1,
1107 0,
1108 &[7u8; 32],
1109 signing.public_key,
1110 Some(PrivateKey::deserialize(&private_bytes).expect("key")),
1111 )
1112 .expect("valid inputs");
1113 let state = SenderKeyState::from_protobuf(state.as_protobuf());
1114
1115 let _ = state.signing_key_private().expect("lazy warm");
1119 assert!(
1120 !state
1121 .signing_key_verifier()
1122 .expect("lazy verifier")
1123 .is_precomputed()
1124 );
1125
1126 let derived = PrivateKey::deserialize(&private_bytes).expect("key");
1127 derived.precompute_signing_cache();
1128 state
1129 .prewarm_signing_key(derived)
1130 .expect("no-op, not error");
1131 state
1132 .prewarm_verifying_key(crate::core::curve::PreparedVerifyingKey::new(
1133 &signing.public_key,
1134 ))
1135 .expect("no-op, not error");
1136
1137 assert!(
1138 state
1139 .signing_key_verifier()
1140 .expect("verifier")
1141 .is_precomputed(),
1142 "the retained verifier must be warm even when the set was inert"
1143 );
1144 assert_eq!(
1145 *state.signing_key_private().expect("key").serialize(),
1146 private_bytes
1147 );
1148 }
1149
1150 #[test]
1152 fn test_sender_message_key_derivation() {
1153 let seed = [0x42u8; 32];
1154 let iteration = 10;
1155
1156 let smk1 = SenderMessageKey::new(iteration, seed);
1157 let smk2 = SenderMessageKey::new(iteration, seed);
1158
1159 assert_eq!(smk1.iteration(), smk2.iteration());
1161 assert_eq!(smk1.iv(), smk2.iv());
1162 assert_eq!(smk1.cipher_key(), smk2.cipher_key());
1163 }
1164
1165 #[test]
1167 fn test_sender_message_key_different_seeds() {
1168 let seed1 = [0x42u8; 32];
1169 let seed2 = [0x43u8; 32];
1170
1171 let smk1 = SenderMessageKey::new(0, seed1);
1172 let smk2 = SenderMessageKey::new(0, seed2);
1173
1174 assert_ne!(smk1.iv(), smk2.iv());
1175 assert_ne!(smk1.cipher_key(), smk2.cipher_key());
1176 }
1177
1178 #[test]
1180 fn test_sender_chain_key_stepping() {
1181 let initial_chain = [0x55u8; 32];
1182 let sck = SenderChainKey::new(0, initial_chain);
1183
1184 let sck1 = sck
1185 .next()
1186 .expect("sender chain key iteration should succeed");
1187 let sck2 = sck1
1188 .next()
1189 .expect("sender chain key iteration should succeed");
1190 let sck3 = sck2
1191 .next()
1192 .expect("sender chain key iteration should succeed");
1193
1194 assert_eq!(sck.iteration(), 0);
1196 assert_eq!(sck1.iteration(), 1);
1197 assert_eq!(sck2.iteration(), 2);
1198 assert_eq!(sck3.iteration(), 3);
1199
1200 assert_ne!(sck.seed(), sck1.seed());
1202 assert_ne!(sck1.seed(), sck2.seed());
1203 assert_ne!(sck2.seed(), sck3.seed());
1204 }
1205
1206 #[test]
1208 fn test_sender_chain_key_message_key() {
1209 let chain = [0x55u8; 32];
1210 let sck = SenderChainKey::new(5, chain);
1211
1212 let smk = sck.sender_message_key();
1213
1214 assert_eq!(smk.iteration(), 5);
1215 assert_eq!(smk.iv().len(), 16);
1216 assert_eq!(smk.cipher_key().len(), 32);
1217 }
1218
1219 #[test]
1221 fn test_sender_chain_key_determinism() {
1222 let chain = [0x77u8; 32];
1223
1224 let sck1 = SenderChainKey::new(0, chain);
1225 let sck2 = SenderChainKey::new(0, chain);
1226
1227 let next1 = sck1
1228 .next()
1229 .expect("sender chain key iteration should succeed");
1230 let next2 = sck2
1231 .next()
1232 .expect("sender chain key iteration should succeed");
1233
1234 assert_eq!(next1.seed(), next2.seed());
1235 assert_eq!(next1.iteration(), next2.iteration());
1236 }
1237
1238 #[test]
1240 fn test_sender_key_state_basic() {
1241 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1242 let keypair = KeyPair::generate(&mut rng);
1243 let chain_key = [0x42u8; 32];
1244
1245 let state = SenderKeyState::new(3, 12345, 0, &chain_key, keypair.public_key, None)
1246 .expect("sender key state should be valid");
1247
1248 assert_eq!(state.chain_id(), 12345);
1249 assert_eq!(state.message_version(), 3);
1250 assert!(state.sender_chain_key().is_some());
1251 assert!(state.signing_key_public().is_ok());
1252 assert!(state.signing_key_private().is_err());
1254 }
1255
1256 #[test]
1257 fn test_sender_key_state_rejects_invalid_chain_key_length() {
1258 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1259 let keypair = KeyPair::generate(&mut rng);
1260
1261 let err = SenderKeyState::new(3, 12345, 0, &[0x42u8; 31], keypair.public_key, None)
1262 .expect_err("invalid chain key length should fail");
1263
1264 assert!(matches!(err, SignalProtocolError::InvalidProtobufEncoding));
1265 }
1266
1267 #[test]
1269 fn test_sender_key_state_with_private_key() {
1270 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1271 let keypair = KeyPair::generate(&mut rng);
1272 let chain_key = [0x42u8; 32];
1273
1274 let state = SenderKeyState::new(
1275 3,
1276 12345,
1277 0,
1278 &chain_key,
1279 keypair.public_key,
1280 Some(keypair.private_key),
1281 )
1282 .expect("sender key state should be valid");
1283
1284 assert!(state.signing_key_public().is_ok());
1285 assert!(state.signing_key_private().is_ok());
1286 }
1287
1288 #[test]
1289 fn signing_key_memo_warms_on_first_use_and_survives_clone() {
1290 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1291 let signing = KeyPair::generate(&mut rng);
1292 let chain_key = [7u8; 32];
1293 let state = SenderKeyState::new(
1294 3,
1295 1,
1296 0,
1297 &chain_key,
1298 signing.public_key,
1299 Some(signing.private_key),
1300 )
1301 .expect("valid inputs");
1302
1303 assert!(state.signing_key_memo_initialized());
1305 assert!(
1306 state
1307 .signing_key_private()
1308 .expect("memo key")
1309 .has_warm_signing_cache()
1310 );
1311
1312 let reloaded = SenderKeyState::from_protobuf(state.as_protobuf());
1316 assert!(!reloaded.signing_key_memo_initialized());
1317 let key = reloaded.signing_key_private().expect("reloaded key");
1318 assert!(key.has_warm_signing_cache());
1319 assert!(reloaded.signing_key_memo_initialized());
1320
1321 let cloned = reloaded.clone();
1323 assert!(cloned.signing_key_memo_initialized());
1324 assert!(
1325 cloned
1326 .signing_key_private()
1327 .expect("cloned key")
1328 .has_warm_signing_cache()
1329 );
1330
1331 assert!(state.verifying_key_memo.get().is_none());
1336 let _ = state.signing_key_verifier().expect("lazy build works");
1337 assert!(state.verifying_key_memo.get().is_some());
1338 let cold = SenderKeyState::from_protobuf(state.as_protobuf());
1339 assert!(cold.verifying_key_memo.get().is_none());
1340 let _ = cold.signing_key_verifier().expect("verifier");
1341 assert!(cold.verifying_key_memo.get().is_some());
1342 assert!(cold.clone().verifying_key_memo.get().is_some());
1343
1344 let msg = b"skmsg";
1346 let sig = key.calculate_signature(msg, &mut rng).expect("sign");
1347 let public = reloaded.signing_key_public().expect("public key");
1348 assert!(public.verify_signature(msg, &sig));
1349 }
1350
1351 #[test]
1353 fn test_sender_key_state_chain_key_update() {
1354 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1355 let keypair = KeyPair::generate(&mut rng);
1356 let chain_key = [0x42u8; 32];
1357
1358 let mut state = SenderKeyState::new(
1359 3,
1360 12345,
1361 0,
1362 &chain_key,
1363 keypair.public_key,
1364 Some(keypair.private_key),
1365 )
1366 .expect("sender key state should be valid");
1367
1368 let initial_sck = state
1369 .sender_chain_key()
1370 .expect("sender chain key should exist");
1371 let next_sck = initial_sck
1372 .next()
1373 .expect("sender chain key iteration should succeed");
1374
1375 state.set_sender_chain_key(next_sck);
1376
1377 let updated_sck = state
1378 .sender_chain_key()
1379 .expect("sender chain key should exist");
1380 assert_eq!(updated_sck.iteration(), 1);
1381 }
1382
1383 #[test]
1385 fn test_sender_key_state_message_key_storage() {
1386 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1387 let keypair = KeyPair::generate(&mut rng);
1388 let chain_key = [0x42u8; 32];
1389
1390 let mut state = SenderKeyState::new(
1391 3,
1392 12345,
1393 0,
1394 &chain_key,
1395 keypair.public_key,
1396 Some(keypair.private_key),
1397 )
1398 .expect("sender key state should be valid");
1399
1400 let smk = SenderMessageKey::new(5, [0xAA; 32]);
1401 state.add_sender_message_key(&smk);
1402
1403 let retrieved = state.remove_sender_message_key(5);
1405 assert!(retrieved.is_some());
1406 assert_eq!(retrieved.expect("message key should exist").iteration(), 5);
1407
1408 let not_found = state.remove_sender_message_key(5);
1410 assert!(not_found.is_none());
1411 }
1412
1413 #[test]
1415 fn test_sender_key_state_message_key_limit() {
1416 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1417 let keypair = KeyPair::generate(&mut rng);
1418 let chain_key = [0x42u8; 32];
1419
1420 let mut state = SenderKeyState::new(
1421 3,
1422 12345,
1423 0,
1424 &chain_key,
1425 keypair.public_key,
1426 Some(keypair.private_key),
1427 )
1428 .expect("sender key state should be valid");
1429
1430 let total_keys = consts::MAX_MESSAGE_KEYS + 100;
1434 for i in 0..total_keys {
1435 let smk = SenderMessageKey::new(i as u32, [0xBB; 32]);
1436 state.add_sender_message_key(&smk);
1437 }
1438
1439 let evicted_count = consts::MESSAGE_KEY_PRUNE_THRESHOLD + 1; for i in 0..evicted_count {
1446 let not_found = state.remove_sender_message_key(i as u32);
1447 assert!(
1448 not_found.is_none(),
1449 "Key at iteration {} should have been evicted",
1450 i
1451 );
1452 }
1453 }
1454
1455 #[test]
1458 fn serialize_roundtrip_preserves_message_key_backlog() {
1459 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1460 let keypair = KeyPair::generate(&mut rng);
1461 let chain_key = [0x42u8; 32];
1462
1463 let mut record = SenderKeyRecord::new_empty();
1464 record
1465 .add_sender_key_state(
1466 3,
1467 12345,
1468 0,
1469 &chain_key,
1470 keypair.public_key,
1471 Some(keypair.private_key),
1472 )
1473 .expect("add_sender_key_state should succeed");
1474
1475 {
1476 let state = record.sender_key_state_mut().expect("state exists");
1477 for i in 0..5u32 {
1478 state.add_sender_message_key(&SenderMessageKey::new(i, [i as u8; 32]));
1479 }
1480 assert!(state.state.sender_message_keys.is_empty());
1482 }
1483
1484 let serialized = record.serialize().expect("serialize");
1485 let mut deserialized = SenderKeyRecord::deserialize(&serialized).expect("deserialize");
1486
1487 let state = deserialized.sender_key_state_mut().expect("state exists");
1488 assert!(state.state.sender_message_keys.is_empty());
1490 for i in 0..5u32 {
1491 let smk = state
1492 .remove_sender_message_key(i)
1493 .unwrap_or_else(|| panic!("key {i} should survive the roundtrip"));
1494 assert_eq!(smk.iteration(), i);
1495 }
1496 }
1497
1498 #[test]
1502 fn backlog_mutation_after_clone_is_isolated() {
1503 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1504 let keypair = KeyPair::generate(&mut rng);
1505 let chain_key = [0x42u8; 32];
1506
1507 let mut original =
1508 SenderKeyState::new(3, 1, 0, &chain_key, keypair.public_key, None).expect("valid");
1509 original.add_sender_message_key(&SenderMessageKey::new(7, [7u8; 32]));
1510
1511 let mut loaded = original.clone();
1514
1515 loaded.add_sender_message_key(&SenderMessageKey::new(8, [8u8; 32]));
1517 assert!(original.remove_sender_message_key(8).is_none());
1518
1519 assert!(loaded.remove_sender_message_key(7).is_some());
1521 assert!(
1522 original.remove_sender_message_key(7).is_some(),
1523 "the cache's copy must keep its key after the loaded copy removed it"
1524 );
1525 }
1526
1527 #[test]
1529 fn test_sender_key_record_basic() {
1530 let record = SenderKeyRecord::new_empty();
1531 assert!(record.sender_key_state().is_err());
1532 }
1533
1534 #[test]
1536 fn test_sender_key_record_add_state() {
1537 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1538 let keypair = KeyPair::generate(&mut rng);
1539 let chain_key = [0x42u8; 32];
1540
1541 let mut record = SenderKeyRecord::new_empty();
1542 record
1543 .add_sender_key_state(
1544 3,
1545 12345,
1546 0,
1547 &chain_key,
1548 keypair.public_key,
1549 Some(keypair.private_key),
1550 )
1551 .expect("sender key state should be valid");
1552
1553 let state = record
1554 .sender_key_state()
1555 .expect("sender key state should exist");
1556 assert_eq!(state.chain_id(), 12345);
1557 }
1558
1559 fn record_with_state(chain_id: u32, seed: u8) -> SenderKeyRecord {
1560 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1561 let keypair = KeyPair::generate(&mut rng);
1562 let mut record = SenderKeyRecord::new_empty();
1563 record
1564 .add_sender_key_state(
1565 3,
1566 chain_id,
1567 0,
1568 &[seed; 32],
1569 keypair.public_key,
1570 Some(keypair.private_key),
1571 )
1572 .expect("state should be valid");
1573 record
1574 }
1575
1576 fn current_iteration(record: &SenderKeyRecord) -> u32 {
1577 record
1578 .sender_key_state()
1579 .expect("test")
1580 .sender_chain_key()
1581 .expect("test")
1582 .iteration()
1583 }
1584
1585 #[test]
1589 fn reservation_survives_roundtrip_and_reload_fast_forwards() {
1590 let mut record = record_with_state(12345, 0x42);
1591 record.reserve_iterations(0);
1592 assert_eq!(
1593 record.reserved_iteration(),
1594 consts::SENDER_CHAIN_RESERVATION_BATCH
1595 );
1596 assert_eq!(
1597 current_iteration(&record),
1598 0,
1599 "reserving does not advance the chain"
1600 );
1601
1602 let reloaded =
1603 SenderKeyRecord::deserialize(&record.serialize().expect("test")).expect("test");
1604 assert_eq!(
1605 reloaded.reserved_iteration(),
1606 consts::SENDER_CHAIN_RESERVATION_BATCH
1607 );
1608 assert_eq!(
1609 current_iteration(&reloaded),
1610 consts::SENDER_CHAIN_RESERVATION_BATCH,
1611 "reload must burn the reserved iterations"
1612 );
1613 }
1614
1615 #[test]
1616 fn cache_incarnation_separates_clean_reload_from_recovery() {
1617 let mut record = record_with_state(12345, 0x42);
1618 record.reserve_iterations(0);
1619 let incarnation = [0xA1; 16];
1620 let replacement = [0xB2; 16];
1621 let bytes = record.serialize_for_store(&incarnation).expect("test");
1622
1623 let clean = SenderKeyRecord::deserialize_for_store(&bytes, &incarnation).expect("test");
1624 assert_eq!(current_iteration(&clean), 0);
1625
1626 let recovered = SenderKeyRecord::deserialize_for_store(&bytes, &replacement).expect("test");
1627 assert_eq!(
1628 current_iteration(&recovered),
1629 consts::SENDER_CHAIN_RESERVATION_BATCH
1630 );
1631
1632 let conservative = SenderKeyRecord::deserialize(&bytes).expect("test");
1633 assert_eq!(
1634 current_iteration(&conservative),
1635 consts::SENDER_CHAIN_RESERVATION_BATCH
1636 );
1637
1638 let legacy = record.serialize().expect("test");
1639 let migrated = SenderKeyRecord::deserialize_for_store(&legacy, &incarnation).expect("test");
1640 assert_eq!(
1641 current_iteration(&migrated),
1642 consts::SENDER_CHAIN_RESERVATION_BATCH
1643 );
1644
1645 let mut duplicated = bytes;
1646 crate::protocol::local_field::encode_store_incarnation(&mut duplicated, &incarnation);
1647 let duplicate_recovery =
1648 SenderKeyRecord::deserialize_for_store(&duplicated, &incarnation).expect("test");
1649 assert_eq!(
1650 current_iteration(&duplicate_recovery),
1651 consts::SENDER_CHAIN_RESERVATION_BATCH
1652 );
1653 }
1654
1655 #[test]
1659 fn rotation_resets_the_lease() {
1660 let mut record = record_with_state(111, 0x42);
1661 record.reserve_iterations(0);
1662 assert_eq!(
1663 record.reserved_iteration(),
1664 consts::SENDER_CHAIN_RESERVATION_BATCH
1665 );
1666
1667 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1668 let kp = KeyPair::generate(&mut rng);
1669 record
1670 .add_sender_key_state(
1671 3,
1672 222,
1673 0,
1674 &[0x43u8; 32],
1675 kp.public_key,
1676 Some(kp.private_key),
1677 )
1678 .expect("test");
1679 assert_eq!(
1680 record.reserved_iteration(),
1681 0,
1682 "rotation must reset the lease"
1683 );
1684 }
1685
1686 #[test]
1690 fn legacy_record_without_field_loads_with_zero() {
1691 let record = record_with_state(12345, 0x42);
1692 let bytes = record.serialize().expect("test");
1693 assert_eq!(
1694 bytes,
1695 record.as_protobuf().encode_to_vec(),
1696 "an unreserved record appends no field"
1697 );
1698 let loaded = SenderKeyRecord::deserialize(&bytes).expect("test");
1699 assert_eq!(loaded.reserved_iteration(), 0);
1700 assert_eq!(
1701 current_iteration(&loaded),
1702 0,
1703 "no reservation, no fast-forward"
1704 );
1705 }
1706
1707 #[test]
1710 fn corrupt_reservation_is_rejected() {
1711 use buffa::encoding::{Tag, WireType, encode_varint};
1712
1713 let record = record_with_state(12345, 0x42);
1714 let mut bytes = record.serialize().expect("test");
1715 let corrupt = consts::MAX_RESERVATION_FAST_FORWARD + 1000;
1716 Tag::new(RESERVED_ITERATION_FIELD, WireType::Varint).encode(&mut bytes);
1717 encode_varint(corrupt as u64, &mut bytes);
1718 assert!(
1719 SenderKeyRecord::deserialize(&bytes).is_err(),
1720 "an implausibly-far reservation must fail closed"
1721 );
1722 }
1723
1724 #[test]
1726 fn test_sender_key_record_state_limit() {
1727 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1728 let chain_key = [0x42u8; 32];
1729
1730 let mut record = SenderKeyRecord::new_empty();
1731
1732 for i in 0..(consts::MAX_SENDER_KEY_STATES + 5) {
1734 let keypair = KeyPair::generate(&mut rng);
1735 record
1736 .add_sender_key_state(
1737 3,
1738 i as u32,
1739 0,
1740 &chain_key,
1741 keypair.public_key,
1742 Some(keypair.private_key),
1743 )
1744 .expect("sender key state should be valid");
1745 }
1746
1747 let chain_ids: Vec<u32> = record.chain_ids_for_logging().collect();
1749 assert!(chain_ids.len() <= consts::MAX_SENDER_KEY_STATES);
1750 }
1751
1752 #[test]
1753 fn test_sender_key_record_deserialize_bounds_state_history() {
1754 let mut state = record_with_state(12345, 0x42).as_protobuf();
1755 let state = state.sender_key_states.pop().expect("test state");
1756 let encoded = SenderKeyRecordStructure {
1757 sender_key_states: vec![state; consts::MAX_SENDER_KEY_STATES + 1],
1758 }
1759 .encode_to_vec();
1760
1761 let record = SenderKeyRecord::deserialize(&encoded).expect("valid record");
1762
1763 assert_eq!(
1764 record.chain_ids_for_logging().len(),
1765 consts::MAX_SENDER_KEY_STATES
1766 );
1767 }
1768
1769 #[test]
1771 fn test_sender_key_record_chain_id_lookup() {
1772 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1773 let keypair1 = KeyPair::generate(&mut rng);
1774 let keypair2 = KeyPair::generate(&mut rng);
1775 let chain_key = [0x42u8; 32];
1776
1777 let mut record = SenderKeyRecord::new_empty();
1778 record
1779 .add_sender_key_state(
1780 3,
1781 111,
1782 0,
1783 &chain_key,
1784 keypair1.public_key,
1785 Some(keypair1.private_key),
1786 )
1787 .expect("sender key state should be valid");
1788 record
1789 .add_sender_key_state(
1790 3,
1791 222,
1792 0,
1793 &chain_key,
1794 keypair2.public_key,
1795 Some(keypair2.private_key),
1796 )
1797 .expect("sender key state should be valid");
1798
1799 let state = record.sender_key_state_for_chain_id(222);
1801 assert!(state.is_some());
1802 assert_eq!(state.expect("state should exist").chain_id(), 222);
1803
1804 let state = record.sender_key_state_for_chain_id(111);
1806 assert!(state.is_some());
1807 assert_eq!(state.expect("state should exist").chain_id(), 111);
1808
1809 let state = record.sender_key_state_for_chain_id(333);
1811 assert!(state.is_none());
1812 }
1813
1814 #[test]
1816 fn test_sender_key_record_serialization() {
1817 let mut rng = rand::make_rng::<rand::rngs::StdRng>();
1818 let keypair = KeyPair::generate(&mut rng);
1819 let chain_key = [0x42u8; 32];
1820
1821 let mut record = SenderKeyRecord::new_empty();
1822 record
1823 .add_sender_key_state(
1824 3,
1825 12345,
1826 5,
1827 &chain_key,
1828 keypair.public_key,
1829 Some(keypair.private_key),
1830 )
1831 .expect("sender key state should be valid");
1832
1833 let serialized = record.serialize().expect("serialization should succeed");
1834 let deserialized =
1835 SenderKeyRecord::deserialize(&serialized).expect("deserialization should succeed");
1836
1837 let state = deserialized
1838 .sender_key_state()
1839 .expect("sender key state should exist");
1840 assert_eq!(state.chain_id(), 12345);
1841 assert!(state.sender_chain_key().is_some());
1842 }
1843
1844 #[test]
1845 fn test_sender_key_record_deserialize_rejects_invalid_chain_seed() {
1846 let record = SenderKeyRecordStructure {
1847 sender_key_states: vec![SenderKeyStateStructure {
1848 sender_key_id: Some(12345),
1849 sender_chain_key: MessageField::some(sender_key_state_structure::SenderChainKey {
1850 iteration: Some(0),
1851 seed: Some(bytes::Bytes::copy_from_slice(&[0x42; 31])),
1852 }),
1853 ..Default::default()
1854 }],
1855 };
1856
1857 let err = SenderKeyRecord::deserialize(&record.encode_to_vec())
1858 .expect_err("invalid sender chain seed should fail");
1859
1860 assert!(matches!(err, SignalProtocolError::InvalidProtobufEncoding));
1861 }
1862
1863 #[test]
1864 fn test_sender_key_record_deserialize_rejects_invalid_message_seed() {
1865 let record = SenderKeyRecordStructure {
1866 sender_key_states: vec![SenderKeyStateStructure {
1867 sender_key_id: Some(12345),
1868 sender_chain_key: MessageField::some(sender_key_state_structure::SenderChainKey {
1869 iteration: Some(0),
1870 seed: Some(bytes::Bytes::copy_from_slice(&[0x42; 32])),
1871 }),
1872 sender_message_keys: vec![sender_key_state_structure::SenderMessageKey {
1873 iteration: Some(1),
1874 seed: Some(bytes::Bytes::copy_from_slice(&[0x43; 31])),
1875 }],
1876 ..Default::default()
1877 }],
1878 };
1879
1880 let err = SenderKeyRecord::deserialize(&record.encode_to_vec())
1881 .expect_err("invalid sender message seed should fail");
1882
1883 assert!(matches!(err, SignalProtocolError::InvalidProtobufEncoding));
1884 }
1885
1886 #[test]
1889 fn test_step_with_message_key_equivalence() {
1890 let chain = [0x99u8; 32];
1891 let sck = SenderChainKey::new(5, chain);
1892
1893 let msg_key_separate = sck.sender_message_key();
1895 let next_chain_separate = sck.next().expect("next should succeed");
1896
1897 let (msg_key_combined, next_chain_combined) = sck
1899 .step_with_message_key()
1900 .expect("step_with_message_key should succeed");
1901
1902 assert_eq!(msg_key_separate.iteration(), msg_key_combined.iteration());
1904 assert_eq!(msg_key_separate.iv(), msg_key_combined.iv());
1905 assert_eq!(msg_key_separate.cipher_key(), msg_key_combined.cipher_key());
1906
1907 assert_eq!(next_chain_separate.seed(), next_chain_combined.seed());
1909 assert_eq!(
1910 next_chain_separate.iteration(),
1911 next_chain_combined.iteration()
1912 );
1913 }
1914
1915 #[test]
1917 fn test_step_with_message_key_chain() {
1918 let initial_chain = [0xBBu8; 32];
1919 let mut chain_separate = SenderChainKey::new(0, initial_chain);
1920 let mut chain_combined = SenderChainKey::new(0, initial_chain);
1921
1922 for i in 0..10 {
1924 let msg_key_sep = chain_separate.sender_message_key();
1925 chain_separate = chain_separate.next().expect("next should succeed");
1926
1927 let (msg_key_comb, next_chain) = chain_combined
1928 .step_with_message_key()
1929 .expect("step_with_message_key should succeed");
1930 chain_combined = next_chain;
1931
1932 assert_eq!(
1934 msg_key_sep.cipher_key(),
1935 msg_key_comb.cipher_key(),
1936 "cipher_key mismatch at iteration {i}"
1937 );
1938
1939 assert_eq!(
1941 chain_separate.seed(),
1942 chain_combined.seed(),
1943 "chain key mismatch at iteration {i}"
1944 );
1945 assert_eq!(chain_separate.iteration(), chain_combined.iteration());
1946 }
1947 }
1948}