commit c4808f6a99bb074f120673c65eac31c0cba23cfa
Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Date:   Fri Mar 4 15:59:15 2022 +0100

    Support big-endian systems
    
    Except for removing the assertion, the only change necessary was to
    byte-swap the arguments when calling the keccak routine.
    
    Tested on (big-endian) IBM Z (s390x-ibm-linux).

diff --git a/src/lib.rs b/src/lib.rs
index 21a8be4..5fd4733 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -6,15 +6,6 @@
 //! Note that docs will only build on nightly Rust until
 //! [RFC 1990 stabilizes](https://github.com/rust-lang/rust/issues/44732).
 
-#[cfg(target_endian = "big")]
-compile_error!(
-    r#"
-This crate doesn't support big-endian targets, since I didn't
-have one to test correctness on.  If you're seeing this message,
-please file an issue!
-"#
-);
-
 mod constants;
 mod strobe;
 mod transcript;
diff --git a/src/strobe.rs b/src/strobe.rs
index ff0436f..8ed64b2 100644
--- a/src/strobe.rs
+++ b/src/strobe.rs
@@ -15,8 +15,24 @@ const FLAG_T: u8 = 1 << 3;
 const FLAG_M: u8 = 1 << 4;
 const FLAG_K: u8 = 1 << 5;
 
-fn transmute_state(st: &mut AlignedKeccakState) -> &mut [u64; 25] {
-    unsafe { &mut *(st as *mut AlignedKeccakState as *mut [u64; 25]) }
+const KECCAK_BLOCK_SIZE: usize = 25;
+
+fn keccakf_u8(st: &mut AlignedKeccakState) {
+    #[cfg(target_endian = "big")]
+    {
+        use byteorder::{ByteOrder, LittleEndian};
+        let mut keccak_block = [0u64; KECCAK_BLOCK_SIZE];
+        LittleEndian::read_u64_into(&st.0, &mut keccak_block);
+        keccak::f1600(&mut keccak_block);
+        LittleEndian::write_u64_into(&keccak_block, &mut st.0);
+    }
+    #[cfg(target_endian = "little")]
+    {
+        fn transmute_state(st: &mut AlignedKeccakState) -> &mut [u64; KECCAK_BLOCK_SIZE] {
+            unsafe { &mut *(st as *mut AlignedKeccakState as *mut [u64; KECCAK_BLOCK_SIZE]) }
+        }
+        keccak::f1600(transmute_state(st));
+    }
 }
 
 /// This is a wrapper around 200-byte buffer that's always 8-byte aligned
@@ -51,7 +67,7 @@ impl Strobe128 {
             let mut st = AlignedKeccakState([0u8; 200]);
             st[0..6].copy_from_slice(&[1, STROBE_R + 2, 1, 0, 1, 96]);
             st[6..18].copy_from_slice(b"STROBEv1.0.2");
-            keccak::f1600(transmute_state(&mut st));
+            keccakf_u8(&mut st);
 
             st
         };
@@ -94,7 +110,7 @@ impl Strobe128 {
         self.state[self.pos as usize] ^= self.pos_begin;
         self.state[(self.pos + 1) as usize] ^= 0x04;
         self.state[(STROBE_R + 1) as usize] ^= 0x80;
-        keccak::f1600(transmute_state(&mut self.state));
+        keccakf_u8(&mut self.state);
         self.pos = 0;
         self.pos_begin = 0;
     }
