1. 15
  1.  

  2. 6

    doing bitmath in Rust feels like a totally different beast — I don’t have the background anxieties that I carry from C, and I trust that my operations will perform consistently across different platforms, word sizes &c.

    I don’t really understand this worry. If you use cstdint.h, you can implement all these routines beautifully. In fact, in C, it looks almost identical to the Rust implementation, with the exception that you manually have to tell Rust that you want your unsigned integers to wrap, like this: Wrapping<u32>. Otherwise, overflows will cause a panic in debug builds and potentially undefined behaviour in release builds.

    All told, Skipjack took me about 8 hours to implement. That’s a lot less time than I expected, given that: I’ve only been programming in Rust for a few months

    I recently implemented the ZipCrypto cipher and various utilities in Rust and I made the exact same experience. Even though I am still new to Rust, I am substantially more productive in Rust than in any other language, including C and C++ which I know for much longer.

    1. 7

      In C there’s a worry that your unsigned short is going to get promoted to signed int as soon as you touch it. This leads to bizarre cases of Undefined Behavior:

      unsigned short multiply(unsigned short x, unsigned short y) {
         unsigned short result = x * y;
         return result;
      }
      

      This is because unsigned short gets promoted to signed int, and the multiplied value may be large enough to overflow 2^31, and that is UB.

      cstdint is just typedefs, so it doesn’t fix any of this.

      1. 2

        That’s crazy, I did not know that. How would you fix this unsigned short function in a portable, correct and performant manner?

        1. 3

          You cast both operands to unsigned int first, or https://c2rust.com/