bee_signing/ternary/wots/
normalize.rs1use crate::ternary::{constants::MESSAGE_FRAGMENT_LENGTH, wots::WotsSecurityLevel};
5
6use bee_crypto::ternary::HASH_LENGTH;
7use bee_ternary::{T1B1Buf, T3B1Buf, TritBuf, Trits, Tryte, T1B1, T3B1};
8
9use thiserror::Error;
10
11#[derive(Debug, Error, PartialEq)]
13pub enum Error {
14 #[error("Invalid message length, should be 243 trits, was {0}.")]
16 InvalidMessageLength(usize),
17}
18
19pub fn normalize(message: &Trits<T1B1>) -> Result<TritBuf<T1B1Buf>, Error> {
24 if message.len() != HASH_LENGTH {
25 return Err(Error::InvalidMessageLength(message.len()));
26 }
27
28 let mut normalized = [0i8; WotsSecurityLevel::High as usize * MESSAGE_FRAGMENT_LENGTH];
29
30 for i in 0..WotsSecurityLevel::High as usize {
31 let mut sum: i16 = 0;
32
33 for j in (i * MESSAGE_FRAGMENT_LENGTH)..((i + 1) * MESSAGE_FRAGMENT_LENGTH) {
34 normalized[j] = i8::try_from(&message[j * 3..j * 3 + 3]).unwrap();
36 sum += i16::from(normalized[j]);
37 }
38
39 while sum > 0 {
40 for t in &mut normalized[i * MESSAGE_FRAGMENT_LENGTH..(i + 1) * MESSAGE_FRAGMENT_LENGTH] {
41 if (*t as i8) > Tryte::MIN_VALUE as i8 {
42 *t -= 1;
43 break;
44 }
45 }
46 sum -= 1;
47 }
48
49 while sum < 0 {
50 for t in &mut normalized[i * MESSAGE_FRAGMENT_LENGTH..(i + 1) * MESSAGE_FRAGMENT_LENGTH] {
51 if (*t as i8) < Tryte::MAX_VALUE as i8 {
52 *t += 1;
53 break;
54 }
55 }
56 sum += 1;
57 }
58 }
59
60 Ok(unsafe {
63 Trits::<T3B1>::from_raw_unchecked(&normalized, normalized.len() * 3)
64 .to_buf::<T3B1Buf>()
65 .encode::<T1B1Buf>()
66 })
67}