wring_twistree/
lib.rs

1#![allow(arithmetic_overflow)]
2//! Wring is a whole-message cipher and Twistree is a hash function.
3//! They use the same key space; keys may be up to 96 bytes long
4//! (they can be arbitrarily long, but longer keys can be susceptible
5//! to related-key attacks). The user-facing modules are `wring` and
6//! `twistree`; the others are internals.
7
8// Used by both wring and twistree
9mod mix3;
10mod rotbitcount;
11mod permute;
12mod keyschedule;
13mod sboxes;
14
15// Used by twistree
16mod blockize;
17mod compress; // uses mix3 and rotbitcount
18
19pub mod wring {
20//! Wring is a whole-message cipher. All the user interface is in the
21//! `Wring` class.
22
23use crate::mix3::*;
24use crate::rotbitcount::*;
25use crate::sboxes::*; // uses keyschedule and permute
26pub use crate::mix3::carmichael;
27
28fn n_rounds(n: usize) -> u32 {
29  let mut ret=3;
30  let mut m=n;
31  while m>=2 {
32    m/=2;
33    ret+=1;
34  }
35  ret
36}
37
38/// Exclusive-ors all bytes in a nonnegative number. The only reason this
39/// function is public is that it's used to generate a long bytestring
40/// for a test.
41pub fn xorn(n: u64) -> u8 { // used for big hash test
42  let mut ret=0u8;
43  let mut i=n;
44  while i>0 {
45    ret ^= i as u8;
46    i = i>>8;
47  }
48  ret
49}
50
51#[derive(Clone)]
52pub struct Wring {
53  sbox: [[u8; 256]; 3],
54  inv_sbox: [[u8; 256]; 3],
55}
56
57impl Wring {
58  /// Creates a new unkeyed Wring.
59  pub fn new() -> Wring {
60    Wring { sbox: NULLKEY, inv_sbox: [[0u8; 256]; 3] }
61  }
62
63  fn set_inv_sbox(&mut self) {
64    for i in 0..3 {
65      for j in 0..256 {
66	self.inv_sbox[i][self.sbox[i][j] as usize]=j as u8;
67      }
68    }
69  }
70
71  /// Sets the S-boxes to linear. Use only for testing.
72  pub fn set_key_linear(&mut self) {
73    for i in 0..3 {
74      for j in 0..256 {
75	self.sbox[i][j]=(j as u8).rotate_left((3*i+1) as u32);
76      }
77    }
78    self.set_inv_sbox();
79  }
80
81  /// Sets the key to a bytestring. Use `.as_bytes` if you have a character string.
82  pub fn set_key(&mut self,str:&[u8]) {
83    sboxes(str,&mut self.sbox);
84    self.set_inv_sbox();
85  }
86
87  fn round_encrypt(&self, src: &mut[u8], dst: &mut[u8], rprime: usize, rond: u32) {
88    assert_eq!(src.len(),dst.len());
89    let len=src.len()/3;
90    mix3parts(src,len,rprime); // this clobbers src
91    for i in 0..src.len() {
92      src[i]=self.sbox[((rond as usize)+i)%3][src[i] as usize];
93    }
94    rot_bitcount(src, dst, 1);
95    for i in 0..dst.len() {
96      dst[i]+=xorn((i^(rond as usize)) as u64);
97    }
98  }
99
100  fn round_decrypt(&self, src: &mut[u8], dst: &mut[u8], rprime: usize, rond: u32) {
101    assert_eq!(src.len(),dst.len());
102    let len=src.len()/3;
103    for i in 0..src.len() { // this clobbers src
104      src[i]-=xorn((i^(rond as usize)) as u64);
105    }
106    rot_bitcount(src, dst, -1);
107    for i in 0..dst.len() {
108      dst[i]=self.inv_sbox[((rond as usize)+i)%3][dst[i] as usize];
109    }
110    mix3parts(dst,len,rprime);
111  }
112
113  /// Encrypts `buf` in place, using a temporary buffer of equal size.
114  pub fn encrypt(&self, buf: &mut[u8]) {
115    let mut tmp:Vec<u8> = Vec::new();
116    tmp.extend_from_slice(buf);
117    let nrond=n_rounds(buf.len());
118    let rprime=if buf.len()<3 {
119      1 // in Haskell, laziness takes care of this
120    } else {
121      find_max_order((buf.len()/3) as u64)
122    } as usize;
123    for i in 0..nrond {
124      if (i&1)==0 {
125	self.round_encrypt(buf,&mut tmp,rprime,i);
126      } else {
127	self.round_encrypt(&mut tmp,buf,rprime,i);
128      }
129    }
130    if (nrond&1)>0 {
131      for i in 0..buf.len() {
132	buf[i]=tmp[i];
133      }
134    }
135  }
136
137  /// Decrypts `buf` in place, using a temporary buffer of equal size.
138  pub fn decrypt(&mut self, buf: &mut[u8]) {
139    let mut tmp:Vec<u8> = Vec::new();
140    tmp.extend_from_slice(buf);
141    if self.inv_sbox[0][0]==self.inv_sbox[0][1] {
142      self.set_inv_sbox();
143    }
144    let nrond=n_rounds(buf.len());
145    let rprime=if buf.len()<3 {
146      1 // in Haskell, laziness takes care of this
147    } else {
148      find_max_order((buf.len()/3) as u64)
149    } as usize;
150    for i in (0..nrond).rev() {
151      if ((nrond-i)&1)==1 {
152	self.round_decrypt(buf,&mut tmp,rprime,i);
153      } else {
154	self.round_decrypt(&mut tmp,buf,rprime,i);
155      }
156    }
157    if (nrond&1)>0 {
158      for i in 0..buf.len() {
159	buf[i]=tmp[i];
160      }
161    }
162  }
163}
164
165#[cfg(test)]
166mod tests {
167  use super::*;
168
169  fn test_vector(wring: &Wring, plain: &[u8], cipher: &[u8]) {
170    let mut buf:Vec<u8> = Vec::new();
171    buf.extend_from_slice(&plain);
172    wring.encrypt(&mut buf);
173    assert_eq!(&buf,&cipher);
174  }
175
176  fn test_new(plain: &[u8]) {
177    let mut wring=Wring::new();
178    let mut dewring=Wring::new();
179    let mut buf:Vec<u8> = Vec::new();
180    wring.set_key(&[]);
181    buf.extend_from_slice(&plain);
182    wring.encrypt(&mut buf);
183    dewring.decrypt(&mut buf);
184    assert_eq!(&buf,&plain);
185  }
186
187  #[test]
188  fn test_vectors() {
189    let zero8=[0u8; 8];
190    let ff8=[255u8; 8];
191    let twistree8="Twistree".as_bytes();
192    let zero9=[0u8; 9];
193    let ff9=[255u8; 9];
194    let allornone9="AllOrNone".as_bytes();
195    let encipher15="EncipherMessage".as_bytes();
196    let mut linear_wring=Wring::new();
197    linear_wring.set_key_linear();
198    let mut empty_wring=Wring::new();
199    empty_wring.set_key(&[]);
200    let mut aerate_wring=Wring::new();
201    aerate_wring.set_key("aerate".as_bytes());
202    let mut χαίρετε_wring=Wring::new();
203    χαίρετε_wring.set_key("Πάντοτε χαίρετε!".as_bytes());
204    let mut двор_wring=Wring::new();
205    let двор_key="Водворетраванатраведрова.Нерубидрованатраведвора!";
206    двор_wring.set_key(двор_key.as_bytes());
207    test_vector(&linear_wring,&zero8,&[0x5e,0x09,0xc0,0x54,0x3c,0x82,0xdc,0xe8]);
208    test_vector(&linear_wring,&ff8,&[0x69,0x9d,0x9d,0xff,0xbc,0x22,0x8a,0x5d]);
209    test_vector(&linear_wring,&twistree8,&[0xbb,0xc3,0x28,0x40,0x8c,0x94,0xae,0xf8]);
210    test_vector(&linear_wring,&zero9,&[0x4a,0xb1,0x99,0x07,0x1b,0x8c,0xd4,0x54,0xaf]);
211    test_vector(&linear_wring,&ff9,&[0x8b,0x6c,0x0a,0x7d,0x32,0x23,0xee,0xc5,0x7f]);
212    test_vector(&linear_wring,&allornone9,&[0xc1,0xd8,0x4e,0x09,0xea,0x44,0xf3,0x0d,0x19]);
213    test_vector(&linear_wring,&encipher15,
214       &[ 0xc5, 0x0e, 0xc1, 0x88, 0xfd, 0x97, 0x89, 0x2d
215	, 0xa3, 0xdf, 0x58, 0x15, 0xd3, 0xf4, 0x8c]);
216    test_vector(&empty_wring,&zero8,&[0x61,0x4b,0xf3,0x34,0x9e,0x21,0xd1,0x21]);
217    test_vector(&empty_wring,&ff8,&[0x22,0xc3,0x6c,0x9f,0xe4,0x27,0xbc,0xce]);
218    test_vector(&empty_wring,&twistree8,&[0x9a,0xcd,0xf5,0xe0,0xb0,0x3c,0x0c,0x32]);
219    test_vector(&empty_wring,&zero9,&[0x72,0x4d,0x2a,0x49,0xc9,0xb3,0x00,0xdb,0x32]);
220    test_vector(&empty_wring,&ff9,&[0xbc,0x05,0xcf,0x4b,0x0f,0x31,0x81,0xba,0x5c]);
221    test_vector(&empty_wring,&allornone9,&[0x06,0x15,0xaf,0x81,0x8b,0x63,0x9c,0xa2,0x9e]);
222    test_vector(&empty_wring,&encipher15,
223       &[ 0x29, 0xb5, 0x8f, 0xd1, 0x67, 0xa7, 0xb3, 0xf6
224	, 0x99, 0x33, 0xa8, 0x47, 0x3c, 0xb4, 0xcf]);
225    test_vector(&aerate_wring,&zero8,&[0x7d,0x9b,0x65,0x67,0xe8,0xa3,0xd2,0x7d]);
226    test_vector(&aerate_wring,&ff8,&[0x2d,0xdc,0xb9,0xb7,0xaa,0x88,0xa2,0xcf]);
227    test_vector(&aerate_wring,&twistree8,&[0xc8,0xbc,0x27,0x92,0x7a,0x8d,0x96,0x97]);
228    test_vector(&aerate_wring,&zero9,&[0xbe,0x74,0x4a,0x6c,0x6b,0x5b,0x2a,0x6c,0x4e]);
229    test_vector(&aerate_wring,&ff9,&[0xb3,0xb5,0xf1,0x9d,0x44,0xa3,0x19,0xd0,0x10]);
230    test_vector(&aerate_wring,&allornone9,&[0xe8,0x23,0xcd,0x4d,0x80,0x5f,0xdb,0xb4,0x0a]);
231    test_vector(&aerate_wring,&encipher15,
232       &[ 0x17, 0x95, 0x06, 0x84, 0x85, 0x6c, 0x0e, 0xed
233	, 0x68, 0x70, 0xe4, 0xdd, 0xeb, 0xd1, 0x92]);
234    test_vector(&χαίρετε_wring,&zero8,&[0xa3,0x5d,0x2e,0x41,0xf3,0x20,0x9e,0x5c]);
235    test_vector(&χαίρετε_wring,&ff8,&[0xbf,0xab,0x12,0xd1,0xa4,0xa7,0x59,0x24]);
236    test_vector(&χαίρετε_wring,&twistree8,&[0xf1,0x45,0xbe,0x34,0x3e,0x0e,0x50,0x44]);
237    test_vector(&χαίρετε_wring,&zero9,&[0x29,0x37,0x34,0x65,0xb4,0xe3,0xd6,0x8b,0x08]);
238    test_vector(&χαίρετε_wring,&ff9,&[0xb9,0x31,0xfb,0xd0,0x08,0x42,0x24,0xe0,0x54]);
239    test_vector(&χαίρετε_wring,&allornone9,&[0xa3,0xab,0x75,0x4b,0xea,0x16,0x54,0xd6,0xa7]);
240    test_vector(&χαίρετε_wring,&encipher15,
241       &[ 0x9b, 0x21, 0x52, 0x31, 0x35, 0x7c, 0xb4, 0x51
242	, 0x85, 0x6d, 0xbd, 0x1b, 0xf0, 0xf6, 0x4d]);
243    test_vector(&двор_wring,&zero8,&[0xb3,0x8c,0xb4,0x4e,0x32,0xef,0xd7,0xc8]);
244    test_vector(&двор_wring,&ff8,&[0x8d,0x0d,0x3c,0x89,0x73,0x22,0xe6,0x6b]);
245    test_vector(&двор_wring,&twistree8,&[0xb7,0x00,0x83,0x84,0x41,0x4d,0x14,0x4b]);
246    test_vector(&двор_wring,&zero9,&[0x84,0xfb,0x3e,0x5b,0x4f,0xce,0x43,0x54,0x84]);
247    test_vector(&двор_wring,&ff9,&[0xed,0xa7,0x7a,0x91,0x3e,0x47,0xa4,0x1e,0x50]);
248    test_vector(&двор_wring,&allornone9,&[0x21,0x15,0x76,0xbc,0x8b,0x29,0x18,0x92,0x21]);
249    test_vector(&двор_wring,&encipher15,
250       &[ 0x5d, 0x6d, 0x0c, 0xa5, 0xfb, 0x0d, 0x38, 0x74
251	, 0x6b, 0xd0, 0x41, 0x10, 0x80, 0xf3, 0x78]);
252    test_vector(&двор_wring,&двор_key.as_bytes(),
253       &[ 0x45, 0x34, 0xac, 0xc5, 0xda, 0x60, 0xe1, 0x0f
254        , 0xbf, 0x17, 0x5d, 0xc7, 0x4c, 0xfc, 0x96, 0xe2
255        , 0xe9, 0x7a, 0x49, 0x58, 0x38, 0x74, 0x0f, 0x30
256        , 0x42, 0x30, 0xcc, 0x39, 0x96, 0x2b, 0x1e, 0xd8
257        , 0x1c, 0x82, 0x76, 0x82, 0x65, 0x09, 0xb3, 0xd8
258        , 0x31, 0xa6, 0xd2, 0xec, 0x36, 0xdd, 0x80, 0x8a
259        , 0x7b, 0x24, 0x56, 0x3e, 0x37, 0xe7, 0x20, 0x68
260        , 0x45, 0x1f, 0x15, 0xa8, 0xf2, 0x17, 0xb3, 0xd5
261        , 0x78, 0x48, 0xef, 0xc5, 0x73, 0xa6, 0x5c, 0x3c
262        , 0x07, 0x11, 0xe2, 0x76, 0xc0, 0xeb, 0xc3, 0xf1
263        , 0x96, 0x24, 0xb4, 0x8e, 0xdf, 0x94, 0xba, 0x4d
264        , 0x67, 0x2f, 0xc5, 0x6f, 0x4a, 0x5d, 0x85, 0x7e
265        ]);
266  }
267
268  #[test]
269  fn test_unkeyed() {
270    test_new("Πάντοτε χαίρετε!".as_bytes());
271  }
272
273}
274
275}
276
277pub mod twistree {
278//! Twistree is a keyed hash function. All the user interface is in
279//! the `Twistree` class.
280
281use crate::sboxes::*; // uses keyschedule and permute
282use crate::blockize::*;
283use crate::compress::*; // uses mix3 and rot_bitcount
284
285
286#[derive(Clone)]
287pub struct Twistree {
288  sbox: [[u8; 256]; 3],
289  tree2: Vec<Vec<u8>>,
290  tree3: Vec<Vec<u8>>,
291  partial_block: Vec<u8>,
292}
293
294impl Twistree {
295  /// Creates a new unkeyed Twistree.
296  pub fn new() -> Twistree {
297    Twistree { sbox: NULLKEY,
298	       tree2: Vec::new(),
299	       tree3: Vec::new(),
300	       partial_block: Vec::new() }
301  }
302
303  /// Sets the S-box to linear. Use only for testing.
304  pub fn set_key_linear(&mut self) {
305    for i in 0..3 {
306      for j in 0..256 {
307	self.sbox[i][j]=(j as u8).rotate_left((3*i+1) as u32);
308      }
309    }
310  }
311
312  /// Sets the key to a bytestring. Use `.as_bytes` if you have a character string.
313  pub fn set_key(&mut self,str:&[u8]) {
314    sboxes(str,&mut self.sbox);
315  }
316
317  /// Initializes a Twistree. Do this before calling `update!` and `finalize!`.
318  pub fn initialize(&mut self) {
319    // Check that the Twistree has been keyed
320    let mut sum:u32=0;
321    for i in 0..3 {
322      for j in 0..256 {
323	sum+=self.sbox[i][j] as u32;
324      }
325    }
326    if sum!=3*255*128 {
327      panic!("call set_key before initialize");
328    }
329    // Check that the Twistree is empty
330    if self.tree2.len()>0 || self.tree3.len()>0 || self.partial_block.len()>0 {
331      panic!("call finalize before calling initialize again");
332    }
333    self.tree2.push(Vec::new());
334    self.tree3.push(Vec::new());
335    self.tree2[0].extend_from_slice(&EXP4_2ADIC[..]);
336    self.tree3[0].extend_from_slice(&EXP4_BASE2[..]);
337  }
338
339  fn compress_pairs_triples(&mut self) {
340    let mut i:usize=0;
341    while self.tree2[i].len()>BLOCKSIZE {
342      if i+1==self.tree2.len() {
343	self.tree2.push(Vec::new());
344      }
345      compress(&self.sbox,&mut self.tree2[i],0);
346      let (extend_from, to_extend) = self.tree2[i..(i+2)].split_at_mut(1);
347      to_extend[0].extend_from_slice(&*extend_from[0]);
348      self.tree2[i].clear();
349      i=i+1;
350    }
351    i=0;
352    while self.tree3[i].len()>2*BLOCKSIZE {
353      if i+1==self.tree3.len() {
354	self.tree3.push(Vec::new());
355      }
356      compress(&self.sbox,&mut self.tree3[i],1);
357      let (extend_from, to_extend) = self.tree3[i..(i+2)].split_at_mut(1);
358      to_extend[0].extend_from_slice(&*extend_from[0]);
359      self.tree3[i].clear();
360      i=i+1;
361    }
362  }
363
364  fn finalize_pairs_triples(&mut self) {
365    for i in 0..self.tree2.len() {
366      compress(&self.sbox,&mut self.tree2[i],0);
367      if i+1<self.tree2.len() {
368	let (extend_from, to_extend) = self.tree2[i..(i+2)].split_at_mut(1);
369	to_extend[0].extend_from_slice(&*extend_from[0]);
370	self.tree2[i].clear();
371      }
372    }
373    for i in 0..self.tree3.len() {
374      compress(&self.sbox,&mut self.tree3[i],1);
375      if i+1<self.tree3.len() {
376	let (extend_from, to_extend) = self.tree3[i..(i+2)].split_at_mut(1);
377	to_extend[0].extend_from_slice(&*extend_from[0]);
378	self.tree3[i].clear();
379      }
380    }
381  }
382
383  /// Updates a Twistree with some data.
384  pub fn update(&mut self,data:&[u8]) {
385    // Check that the Twistree has been initialized
386    if self.tree2.len()==0 || self.tree3.len()==0 {
387      panic!("call initialize before update");
388    }
389    let blocks=blockize(data,&mut self.partial_block);
390    for i in 0..blocks.len() {
391      self.tree2[0].extend(&blocks[i]);
392      self.tree3[0].extend(&blocks[i]);
393      self.compress_pairs_triples();
394    }
395  }
396
397  /// Completes processing the data in the Twistree and returns the hash.
398  /// Use after `initialize!` and `update!`.
399  pub fn finalize(&mut self) -> Vec<u8> {
400    // Check that the Twistree has been initialized
401    if self.tree2.len()==0 || self.tree3.len()==0 {
402      panic!("call initialize before finalize");
403    }
404    let last_block=pad(&mut self.partial_block);
405    self.tree2[0].extend(&last_block);
406    self.tree3[0].extend(&last_block);
407    self.compress_pairs_triples();
408    self.finalize_pairs_triples();
409    let mut fruit=self.tree2.swap_remove(self.tree2.len()-1);
410    fruit.extend(self.tree3.swap_remove(self.tree3.len()-1));
411    self.tree2.clear();
412    self.tree3.clear();
413    compress(&self.sbox,&mut fruit,2);
414    fruit
415  }
416
417  /// convenience function if the data all fit in RAM
418  pub fn hash(&mut self,data:&[u8]) -> Vec<u8> {
419    self.initialize();
420    self.update(data);
421    self.finalize()
422  }
423}
424
425#[cfg(test)]
426mod tests {
427  use super::*;
428  use crate::wring::xorn;
429
430  fn test_vector(twistree: &mut Twistree, plain: &[u8], hash: &[u8]) {
431    let mut buf:Vec<u8> = Vec::new();
432    buf.extend_from_slice(&plain);
433    twistree.initialize();
434    twistree.update(&buf);
435    let hish=twistree.finalize();
436    assert_eq!(&hish,&hash);
437  }
438
439  #[test]
440  fn test_vectors() {
441    let text31="בראשית ברא אלהים ".as_bytes();
442    let text33="árvíztűrő tükörfúrógépek".as_bytes();
443    let text96="Водворетраванатраведрова.Нерубидрованатраведвора!".as_bytes();
444    let mut text59049=[0u8;59049];
445    // This long test vector is intended for testing parallel implementations.
446    for i in 0..59049 {
447      text59049[i]=xorn((i+1) as u64);
448    }
449    let mut linear_twistree=Twistree::new();
450    linear_twistree.set_key_linear();
451    let mut empty_twistree=Twistree::new();
452    empty_twistree.set_key(&[]);
453    let mut aerate_twistree=Twistree::new();
454    aerate_twistree.set_key("aerate".as_bytes());
455    let mut χαίρετε_twistree=Twistree::new();
456    χαίρετε_twistree.set_key("Πάντοτε χαίρετε!".as_bytes());
457    let mut двор_twistree=Twistree::new();
458    двор_twistree.set_key("Водворетраванатраведрова.Нерубидрованатраведвора!".as_bytes());
459    test_vector(&mut linear_twistree,&[],&
460      [ 0x51, 0xce, 0xe6, 0x7e, 0xbc, 0x77, 0xf0, 0xc8
461      , 0xab, 0xa4, 0x8c, 0x39, 0x9a, 0x33, 0x46, 0xe7 
462      , 0xe2, 0x1e, 0xc9, 0xc1, 0x39, 0x8f, 0xdb, 0x99
463      , 0xb2, 0x9c, 0x41, 0x37, 0xd0, 0xd7, 0x53, 0xc2
464      ]);
465    test_vector(&mut linear_twistree,&text31,&
466      [ 0x20, 0x8d, 0x61, 0x88, 0x7c, 0x13, 0x27, 0x9f
467      , 0x41, 0x26, 0x48, 0x31, 0x5e, 0x64, 0x2b, 0x0e 
468      , 0xb1, 0xf1, 0xb6, 0xd2, 0xf9, 0x8f, 0x20, 0x29
469      , 0x15, 0xf7, 0xf1, 0xe2, 0x31, 0xf3, 0x74, 0x18
470      ]);
471    test_vector(&mut linear_twistree,&text33,&
472      [ 0x61, 0x6b, 0x91, 0xe4, 0x6f, 0xab, 0x4c, 0x69
473      , 0x03, 0xea, 0x9f, 0x2b, 0xc0, 0x0e, 0x90, 0xa2 
474      , 0xe4, 0x40, 0xc3, 0x87, 0x1c, 0xa2, 0x27, 0x5a
475      , 0x12, 0x10, 0x59, 0x4d, 0x8b, 0x33, 0x7f, 0x9e
476      ]);
477    test_vector(&mut linear_twistree,&text96,&
478      [ 0x34, 0x82, 0x7e, 0xbe, 0x74, 0x06, 0x8e, 0xe1
479      , 0xe7, 0x37, 0xaf, 0x31, 0x93, 0x2c, 0xd1, 0x85 
480      , 0x35, 0x8c, 0x32, 0x1c, 0x0c, 0xc1, 0xda, 0x47
481      , 0x97, 0x57, 0x18, 0xca, 0x57, 0xe3, 0xc8, 0xf8
482      ]);
483    test_vector(&mut empty_twistree,&[],&
484      [ 0x5b, 0x62, 0x5d, 0xeb, 0x4f, 0xa6, 0x92, 0xae
485      , 0x56, 0xf9, 0xba, 0x20, 0xf6, 0xb4, 0xc1, 0x05 
486      , 0xff, 0x92, 0x92, 0x3c, 0x7e, 0x84, 0xee, 0x2f
487      , 0x83, 0xc1, 0x0d, 0xc2, 0x8f, 0xda, 0xa3, 0x7b
488      ]);
489    test_vector(&mut empty_twistree,&text31,&
490      [ 0x4c, 0xc9, 0x2e, 0x58, 0xf2, 0x80, 0xaf, 0x58
491      , 0x3e, 0x39, 0x6f, 0x3a, 0x9b, 0x7a, 0xdb, 0x59 
492      , 0x65, 0x63, 0xb1, 0x28, 0x96, 0x68, 0x29, 0x83
493      , 0xe4, 0x38, 0x1f, 0x79, 0x62, 0x78, 0x44, 0x0b
494      ]);
495    test_vector(&mut empty_twistree,&text33,&
496      [ 0x3b, 0x8c, 0x2e, 0x6d, 0x7a, 0x29, 0x0a, 0x84
497      , 0xf4, 0x40, 0xe8, 0x37, 0xc9, 0xd5, 0x8c, 0x64 
498      , 0x11, 0x2a, 0x42, 0x17, 0x92, 0xd3, 0x33, 0xa0
499      , 0x24, 0xbe, 0xa3, 0x3f, 0x4a, 0x4b, 0x18, 0x1f
500      ]);
501    test_vector(&mut empty_twistree,&text96,&
502      [ 0x4c, 0x19, 0x30, 0x4a, 0xae, 0x2a, 0x92, 0xba
503      , 0x9c, 0x05, 0x69, 0x37, 0xd7, 0xfc, 0x36, 0x2d 
504      , 0x29, 0x94, 0x8e, 0xdc, 0x3c, 0x56, 0x4f, 0x50
505      , 0x08, 0xa7, 0x5b, 0x0a, 0x06, 0x95, 0x90, 0xee
506      ]);
507    test_vector(&mut aerate_twistree,&[],&
508      [ 0x0a, 0x4b, 0x98, 0x44, 0x15, 0xe7, 0x8b, 0xe2
509      , 0xfe, 0xba, 0xf5, 0xe5, 0x51, 0x46, 0xe0, 0x05 
510      , 0xc8, 0x0c, 0x13, 0x6b, 0xfb, 0x2f, 0x6f, 0xa4
511      , 0xf6, 0x08, 0xbb, 0xa6, 0xe9, 0xf3, 0x35, 0xda
512      ]);
513    test_vector(&mut aerate_twistree,&text31,&
514      [ 0x73, 0xd6, 0xe9, 0xc0, 0x63, 0xd5, 0x3c, 0xec
515      , 0x4d, 0xd8, 0x3f, 0x89, 0x9f, 0x15, 0xf3, 0xf8 
516      , 0xe6, 0x7e, 0xfb, 0xc5, 0x46, 0x4e, 0x11, 0x60
517      , 0x9c, 0x0b, 0x75, 0xed, 0x35, 0x23, 0x56, 0x60
518      ]);
519    test_vector(&mut aerate_twistree,&text33,&
520      [ 0x77, 0x0b, 0xe3, 0xbe, 0xc4, 0x9c, 0xf9, 0xd0
521      , 0xd1, 0x46, 0xda, 0x03, 0xea, 0xe5, 0x60, 0x4e 
522      , 0x47, 0xec, 0xf1, 0x54, 0xe8, 0x6b, 0x63, 0x93
523      , 0x59, 0x52, 0xf0, 0x95, 0xb7, 0x32, 0x64, 0x0f
524      ]);
525    test_vector(&mut aerate_twistree,&text96,&
526      [ 0x00, 0x0a, 0x4c, 0x5e, 0x61, 0xd8, 0xb0, 0x14
527      , 0xfc, 0xe6, 0x46, 0xf9, 0xd3, 0x0f, 0xb2, 0x71 
528      , 0x43, 0x8c, 0xc4, 0x3f, 0x7f, 0x72, 0x0a, 0xfe
529      , 0xe1, 0xa3, 0xff, 0xd9, 0x5d, 0xe1, 0x65, 0x76
530      ]);
531    test_vector(&mut χαίρετε_twistree,&[],&
532      [ 0x33, 0x69, 0xba, 0x2b, 0x72, 0x58, 0x6a, 0x78
533      , 0x6f, 0xc5, 0xd7, 0xbe, 0x3c, 0x80, 0xac, 0x24 
534      , 0x87, 0xb8, 0x6e, 0x2e, 0x1c, 0x4f, 0xee, 0x76
535      , 0x71, 0x49, 0x51, 0x7c, 0x58, 0xfb, 0x2e, 0x5a
536      ]);
537    test_vector(&mut χαίρετε_twistree,&text31,&
538      [ 0xef, 0x78, 0x8f, 0x13, 0xb6, 0xb7, 0xd7, 0x9c
539      , 0xae, 0xce, 0xbe, 0x56, 0x80, 0x14, 0x4a, 0x37 
540      , 0x49, 0x26, 0xd6, 0x88, 0x69, 0x3e, 0x66, 0xd1
541      , 0xc6, 0xeb, 0x82, 0x37, 0x57, 0x53, 0xe1, 0x13
542      ]);
543    test_vector(&mut χαίρετε_twistree,&text33,&
544      [ 0xf5, 0xde, 0x17, 0xa3, 0xc6, 0xde, 0x7e, 0x4f
545      , 0x17, 0xf6, 0xef, 0x3a, 0xe5, 0x7b, 0x1e, 0xc3 
546      , 0xa4, 0x9d, 0x9c, 0x7d, 0x85, 0x42, 0xf4, 0xb3
547      , 0xd4, 0x85, 0x94, 0x4d, 0x73, 0x98, 0x79, 0x80
548      ]);
549    test_vector(&mut χαίρετε_twistree,&text96,&
550      [ 0x51, 0x35, 0x1a, 0xb4, 0x7b, 0x42, 0x96, 0xab
551      , 0x8c, 0xcd, 0xb7, 0xca, 0x12, 0x1b, 0xe2, 0x26 
552      , 0x73, 0x0e, 0x43, 0xd4, 0x42, 0x70, 0xd6, 0x93
553      , 0x0c, 0xee, 0xe2, 0xfe, 0x87, 0x88, 0x26, 0xee
554      ]);
555    test_vector(&mut двор_twistree,&[],&
556      [ 0x4e, 0xfa, 0x85, 0x3a, 0xa1, 0xd2, 0x57, 0x43
557      , 0x87, 0x44, 0xf4, 0x37, 0x6d, 0x11, 0x40, 0x73 
558      , 0x38, 0x22, 0xc8, 0xd2, 0x2f, 0x0b, 0xb1, 0xba
559      , 0x06, 0x3b, 0x8e, 0x55, 0x54, 0x70, 0x76, 0x4c
560      ]);
561    test_vector(&mut двор_twistree,&text31,&
562      [ 0xf9, 0x1d, 0x93, 0x79, 0x4e, 0x6e, 0xdd, 0x91
563      , 0x92, 0xcd, 0x47, 0xc4, 0xe8, 0xd2, 0xf9, 0xba 
564      , 0x0b, 0x5e, 0xca, 0x38, 0x92, 0xa8, 0xf9, 0x6e
565      , 0x2a, 0xdc, 0x49, 0xaa, 0x0c, 0x0b, 0x4d, 0xff
566      ]);
567    test_vector(&mut двор_twistree,&text33,&
568      [ 0xde, 0x94, 0xa0, 0x0c, 0xf4, 0x4c, 0x5a, 0xe2
569      , 0xfb, 0xf7, 0x08, 0x3c, 0x9a, 0xdb, 0xda, 0x25 
570      , 0xa0, 0x2a, 0x01, 0xfb, 0x68, 0x81, 0x94, 0x88
571      , 0x8b, 0xc2, 0xbe, 0x1d, 0x6c, 0xae, 0x7b, 0x9c
572      ]);
573    test_vector(&mut двор_twistree,&text96,&
574      [ 0xb1, 0x1b, 0x84, 0x9d, 0xf7, 0xb4, 0x15, 0xa3
575      , 0xf9, 0xdc, 0x69, 0x47, 0xe1, 0xd2, 0xc0, 0x20 
576      , 0x64, 0x0d, 0x8f, 0xf6, 0x79, 0xb6, 0x7b, 0x69
577      , 0xbc, 0x70, 0xe1, 0x2e, 0x3d, 0xd7, 0xeb, 0x57
578      ]);
579    test_vector(&mut двор_twistree,&text59049,&
580      [ 0xd2, 0xe3, 0x0f, 0x01, 0xa0, 0x32, 0x27, 0x51
581      , 0x4e, 0x56, 0x44, 0xf1, 0x8f, 0x2e, 0x3e, 0xeb 
582      , 0xdb, 0x14, 0x30, 0xba, 0x96, 0x2c, 0x47, 0x24
583      , 0x4b, 0x79, 0x39, 0x58, 0xbc, 0x4f, 0x79, 0x25
584      ]);
585  }
586
587}
588
589}