I'm working on an implementation of a Galois field for a cryptographic library.
I would like to have precomputed tables for operations in Gf(256).
Existing implementations either use ONCE_INIT to generate the table when the program launches or have the table hardcoded in the source code.
I'm trying to generate the table (implemented as a struct) at compile time elegantly without having to hardcode it. I have looked into using macros but it appears that they alone won't be able to provide the operations I need to compute the table.
I started looking into compiler plugins, is that the right tool for the job? Or anyone has an alternative that wouldn't require me to move to experimental versions of the compiler?
LALRPOP uses this approach to generate parsers at compile time, but this is a terrible example. You basically need to generate a source code of the struct and write it to some file in src directory. I think you can avoid string manipulation if you use Debug:
#[derive(Debug)]
struct S {
...
}
fn main() {
let s: S = compute();
let source_code = format!("pub const precompiled_table: S = {:#?}", s);
write_source_code_to_file_in_src("src/table.rs", &source_code);
}
Thanks @sorear for the links. Any recommendations? DJB's recommendations seem overly complex for my use case since a timing side-channel is not a major concern.
Otherwise your best option is probably bit-slicing.
Are you expecting to avoid timing attacks by way of keeping a low profile (people target OpenSSL, not FeelingRustyCrypt) or is there a more specific reason you expect to be protected from side channels? Between cross-VM attacks and the steady increase of Javascript's capabilities, I'm rather pessimistic about the future of secret array indices.