Usuba is a programming language to write bitsliced code. It compiles optimized to C code (+ intrinsics).
Go to our website to find more about Usuba.
In particular, the following blog articles are a good introduction:
-
Usuba - The Genesis explains the motivation behind Usuba.
-
Bitslicing presents the bitslicing technique, which is the basis of Usuba.
To go into more details, read our published papers about Usuba:
-
Darius Mercadier, Pierre-Evariste Dagand. Usuba: High-Throughput and Constant-Time Ciphers, by Construction, PLDI 2019.
-
Darius Mercadier, Pierre-Évariste Dagand, Lionel Lacassagne, Gilles Muller, Usuba, Optimizing & Trustworthy Bitslicing Compiler, WPMVP 2018.
Finally, some additional resources that could be useful:
-
Timeless: One-page presentation of Usuba
-
June 2019: Technical presentation of Usuba @PLDI'19
-
February 2019: High-level presentation of Usuba @Inria's Junior Seminar
Usuba is written in OCaml. To compile and run Usuba, you will need to install Opam, the OCaml package manager, on your system.
If you have never used Opam before, you need to initialize it (otherwise, skip this step):
$ opam init
To automatically bring up its dependencies, setup a local Opam distribution, using the following commands:
$ opam switch create . --deps-only --with-doc --with-test
$ eval $(opam env)
To build the compiler, type:
$ make
If everything goes well, you can interact with the compiler with
$ ./usubac -help
To run all the tests, type:
$ make test
A minimal development & benchmark environment is specified in the
Docker file ./docker/Dockerfile starting from a Bullseye Debian
distribution. You can either use this image through
cd docker; make build && make benchor take inspiration from it to reproduce the build environment on your local machine.
A few examples of Usuba codes:
- bitslice DES (and the generated C code),
- bitslice AES (and the generated C code),
- n-slice AES (and the generated C code),
- 32-slice Serpent (and the generated C code),
- 32-slice Chacha20 (and the generated C code).
If you are familiar with Perl, an easy way to see the compiler an action is to look at the scripts in the directory checks/correctness that compile a few Usuba codes, run them and make sure they produce the expected results.
To compile an Usuba file (.ua), you need to invoke ./usubac <options> <source.ua> (the Usuba source file must be the last argument).
I strongly recommand always using the flag -no-sched when doing pure
bitslicing (it disables a few experimental options, and reduces the
amount of code loaded). The option -no-arr-entry might also be
usefull for small functions (combined with -no-arr).
The list of flags can be obtained by running ./usubac -help.
For instance, to compile a bitslice AES:
./usubac -B -o aes.c -no-sched examples/samples/usuba/aes.ua
The C code generated by Usuba uses macros to achieve genericity. This
macros are loaded with the instruction #include "XXX.h" at the
begining of the C files generated, where XXX is one of STD, SSE,
AVX (which should be AVX2), AVX512, Neon, AltiVec. Those
headers are located in the directory arch.
If you change some types in Config.conf or Usuba_AST, you should create a branch for these changes only since they're not supposed to change the behaviour of passes. Once this is done, update the unit_tests submodule with:
-
This will populate the
./scripts/run-selected.sh -- -dump-steps ast -dump-steps-dir unit_tests/rsc
rscdir - Go in
unit_testsand execute:./generate.sh --steps-dir rsc
This way, the unit_tests will be able to check that your work on the rest of usuba doesn't break the expected behaviour and you can start working on a new branch with algorithmic changes.