├── .github └── workflows │ ├── check_fmt.yml │ └── make_and_test.yml ├── .gitignore ├── .gitmodules ├── .ocamlformat ├── .ocamlformat-ignore ├── CHANGES.md ├── LICENSE ├── Makefile ├── README.md ├── TODO.md ├── arch ├── AVX.h ├── AVX512.h ├── AltiVec.h ├── FAME │ ├── .gitignore │ ├── FAME.h │ ├── FAME_FD.h │ ├── FAME_TI.h │ ├── FAME_instrs.h │ ├── FAME_rand.h │ ├── Readme.md │ ├── custom_instrs_hard.h │ ├── custom_instrs_soft.h │ └── test_FAME.c ├── MASKED.h ├── MASKED_UA.h ├── Neon.h ├── SSE.h └── STD.h ├── bin └── cli │ ├── dune │ └── main.ml ├── checks └── correctness │ ├── ace │ └── main.c │ ├── ace_masked │ └── main.c │ ├── aes │ ├── aes_ctr.pl │ ├── avx │ │ ├── aes_bs.c │ │ ├── api.h │ │ ├── crypto_stream.h │ │ ├── key_sched.c │ │ └── stream.c │ ├── main.c │ ├── sse │ │ ├── aes_bs.c │ │ ├── api.h │ │ ├── crypto_stream.h │ │ ├── key_sched.c │ │ └── stream.c │ ├── std │ │ ├── aes_bs.c │ │ ├── api.h │ │ ├── crypto_stream.h │ │ ├── key_sched.c │ │ └── stream.c │ └── stream.h │ ├── aes_mslice │ ├── aes.pl │ ├── input.txt │ ├── key_sched.c │ └── main.c │ ├── ascon │ └── main.c │ ├── ascon_masked │ └── main.c │ ├── chacha20 │ ├── AVX │ │ ├── AVX.h │ │ ├── api.h │ │ └── stream.c │ ├── SSE │ │ ├── SSE.h │ │ ├── api.h │ │ └── stream.c │ ├── STD │ │ ├── STD.h │ │ ├── api.h │ │ └── stream.c │ ├── crypto_stream.h │ ├── main_verif.c │ └── stream.h │ ├── check_ace.pl │ ├── check_ace_masked.pl │ ├── check_aes.pl │ ├── check_aes_mslice.pl │ ├── check_ascon.pl │ ├── check_ascon_masked.pl │ ├── check_chacha20.pl │ ├── check_clyde_bitslice.pl │ ├── check_clyde_masked.pl │ ├── check_clyde_vslice.pl │ ├── check_des.pl │ ├── check_drygascon.pl │ ├── check_gift.pl │ ├── check_gimli_bitslice.pl │ ├── check_gimli_masked.pl │ ├── check_gimli_vslice.pl │ ├── check_photon.pl │ ├── check_pyjamask.pl │ ├── check_pyjamask_masked.pl │ ├── check_serpent.pl │ ├── check_skinny_bitslice.pl │ ├── check_skinny_vslice.pl │ ├── check_spongent.pl │ ├── check_subterranean.pl │ ├── check_xoodoo.pl │ ├── clyde │ └── main.c │ ├── clyde_masked │ └── main.c │ ├── des │ ├── main.c │ └── ref_usuba.c │ ├── drygascon │ └── main.c │ ├── gift │ └── main.c │ ├── gimli │ └── main.c │ ├── gimli_masked │ └── main.c │ ├── photon │ └── main.c │ ├── pyjamask │ ├── api.h │ ├── main.c │ ├── pyjamask.c │ └── pyjamask.h │ ├── pyjamask_masked │ ├── api.h │ ├── main.c │ ├── pyjamask.c │ └── pyjamask.h │ ├── serpent │ ├── main.c │ ├── ref.c │ ├── sbox_for_key.c │ ├── serpent.h │ └── serpentsboxes.h │ ├── skinny │ └── main.c │ ├── spongent │ └── main.c │ ├── subterranean │ └── main.c │ └── xoodoo │ └── main.c ├── cmp.pl ├── cmp_opts.pl ├── config.json.help ├── configure ├── configure.ml ├── docker ├── Dockerfile └── Makefile ├── docs ├── grammar.org └── grammar.pdf ├── dune-project ├── install_deps.sh ├── instr.pl ├── instr_arm.pl ├── pp ├── dune └── usuba_pp.ml ├── reduce.pl ├── results.org ├── run_checks.pl ├── scripts ├── dune ├── run-selected.ml └── run-selected.sh ├── src ├── ansi_terminal.ml ├── assert_lang.ml ├── backtrace.ml ├── basic_utils.ml ├── c_gen │ ├── nodes_to_c.ml │ ├── nodes_to_c_fdti.ml │ ├── nodes_to_c_masked.ml │ ├── nodes_to_c_ua_masked.ml │ ├── runtimes │ │ └── genC_standalone.ml │ └── usuba_to_c.ml ├── clear_origins.ml ├── config.mli ├── dune ├── errors.ml ├── ident.ml ├── ident.mli ├── interp.ml ├── maskverif │ └── usuba_to_maskverif.ml ├── normalization │ ├── clean.ml │ ├── convert_tables.ml │ ├── expand_array.ml │ ├── expand_multiples.ml │ ├── expand_parameters.ml │ ├── expand_permut.ml │ ├── fix_all_params.ml │ ├── fix_dim.ml │ ├── init_scheduler.ml │ ├── mask.ml │ ├── monomorphize.ml │ ├── norm_tuples.ml │ ├── normalize.ml │ ├── normalize_core.ml │ ├── normalize_inner_core.ml │ ├── remove_sync.ml │ ├── sbox_index.ml │ ├── shift_tuples.ml │ ├── unfold_unnest.ml │ └── unroll.ml ├── optimization │ ├── CSE.ml │ ├── constant_folding.ml │ ├── copy_propagation.ml │ ├── fuse_loop_general.ml │ ├── fuse_loops.ml │ ├── get_live_var.ml │ ├── inline.ml │ ├── inline_core.ml │ ├── interleave.ml │ ├── linearize_arrays.ml │ ├── optimize.ml │ ├── pre_schedule.ml │ ├── remove_dead_code.ml │ ├── scheduler.ml │ ├── share_var.ml │ ├── simple_opts.ml │ └── vital_inline.ml ├── parsing │ ├── dune │ ├── lexer.mll │ ├── parser.messages │ ├── parser.mly │ ├── parser_api.ml │ └── parser_helper.ml ├── pass_runner.ml ├── perfs.ml ├── prelude.ml ├── prelude.mli ├── rename.ml ├── syntax.ml ├── syntax.mli ├── tightprove │ ├── parsing │ │ ├── dune │ │ ├── lexer_tp.mll │ │ ├── parser_api_tp.ml │ │ └── parser_tp.mly │ ├── print_tp.ml │ ├── tightprove.ml │ ├── tightprove_to_usuba.ml │ ├── tp_AST.ml │ ├── tp_IO.ml │ └── usuba_to_tightprove.ml ├── usuba_AST.ml ├── usuba_AST.mli ├── usuba_print.ml ├── utils.ml └── verification │ ├── bdd_verif.ml │ ├── soundness.ml │ ├── type_checker.ml │ └── variable_binding.ml ├── subroutines.pl ├── tests ├── rsc │ ├── invalid │ │ └── typing │ │ │ ├── test1.ua │ │ │ └── test2.ua │ └── valid │ │ └── typing │ │ └── test.ua ├── test_parsing.ml └── test_parsing.sh ├── usuba-mode.el ├── usuba.opam ├── usuba_lib.opam └── usuba_pp.opam /.github/workflows/check_fmt.yml: -------------------------------------------------------------------------------- 1 | name: Check formatting 2 | 3 | # For any push and pull request we try to build the project 4 | on: [push,pull_request] 5 | 6 | env: 7 | OCAML_DEFAULT_VERSION: 4.14.0 8 | # Add OPAMYES=true to the environment, this is usefill to replace `-y` option 9 | # in any opam call 10 | OPAMYES: true 11 | 12 | jobs: 13 | check-format: 14 | # Basic test to check if the project can be built (using dune build) 15 | # This test also check that `.opam` files are synced with dune-project 16 | # If this test fails, no more make building test are done 17 | name: Check Format 18 | 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | # Checkout the code of the current branch 23 | - name: Checkout code 24 | uses: actions/checkout@v2 25 | 26 | # Retrieve the opam cache with unique key 27 | # A new cache is created/used if the `.opam` files changes or 28 | # if we use another ocaml version 29 | # This action only retrieve the .opam/ directory 30 | - name: Retrieve opam cache 31 | uses: actions/cache@v2 32 | id: cache-opam 33 | with: 34 | path: ~/.opam 35 | key: v2-${{ runner.os }}-test-actions-${{ env.OCAML_DEFAULT_VERSION }}-${{ hashFiles('*.opam') }} 36 | 37 | # Get an OCaml environment with opam installed and the proper ocaml version 38 | # opam will use opam cache environment if retrieved 39 | - name: Use OCaml ${{ env.OCAML_DEFAULT_VERSION }} 40 | uses: avsm/setup-ocaml@v1 41 | with: 42 | ocaml-version: ${{ env.OCAML_DEFAULT_VERSION }} 43 | 44 | # Install dependencies (TODO when we have a clean repo, not now) 45 | # - name: opam install deps 46 | # run: opam install ./*.opam --deps-only 47 | 48 | # Make sure the env is synced 49 | - name: eval opam env 50 | run: eval $(opam env) 51 | 52 | - name: install ocaml dependencies 53 | run: opam install --deps-only . 54 | 55 | - name: install ocamlformat 56 | run: opam install ocamlformat 57 | 58 | # Export opam's path 59 | - name: export opam path 60 | run: | 61 | echo "$HOME/.opam/${{ env.OCAML_DEFAULT_VERSION }}/bin" >> $GITHUB_PATH 62 | 63 | # Generate config.ml file 64 | - name: configure 65 | run: ./configure 66 | 67 | - name: check ocamlformat 68 | run: dune build @fmt || (echo \"dune build @fmt failed. You should dune build @fmt --auto-promote and push.\"; exit 2) 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | _opam 3 | *.native 4 | *~ 5 | *.cmo 6 | *.cmi 7 | *.cmx 8 | *.o 9 | *.out 10 | *des_*_round* 11 | gcc-no* 12 | gcc-w* 13 | clang-no* 14 | clang-w* 15 | icc-w* 16 | icc-no* 17 | tcc-w* 18 | tcc-no* 19 | z3 20 | usubac 21 | supercop-data 22 | 23 | # Generated files 24 | config.ml 25 | lexer_tp.ml 26 | 27 | observations.org 28 | 29 | # Unit tests submodule 30 | unit_tests/ 31 | 32 | fix_all_params.ml 33 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "unit_tests"] 2 | path = unit_tests 3 | url = https://github.com/usubalang/unit_tests 4 | -------------------------------------------------------------------------------- /.ocamlformat: -------------------------------------------------------------------------------- 1 | profile = default 2 | version = 0.23.0 3 | -------------------------------------------------------------------------------- /.ocamlformat-ignore: -------------------------------------------------------------------------------- 1 | ciphers/* 2 | ciphers/*/* 3 | ciphers/*/*/* 4 | ciphers/*/*/*/* 5 | 6 | # Temporary 7 | src/normalization/sbox_index.ml 8 | src/normalization/fix_all_params.ml 9 | src/config.ml 10 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # Changes 2 | 3 | Here are the changes that were added to Usuba. When creating a pull request, contributors should make sure that they edited this file to document their changes since it makes it easier to find them. 4 | 5 | ## dump_steps [#29](https://github.com/usubalang/usuba/pull/29) 6 | 7 | ### New command line arguments to dump the Usuba AST between each normalisation/optimisation step: 8 | 9 | - `-dump-steps ` Dump the modified Usuba files at each step. The `` is: 10 | - `usuba`: dump the AST to a `.ua` file as an Usuba program 11 | - `sexp`: dump the AST to a `.ua` file as a s-expression 12 | - `ast`: dump the AST to a `.ml` file as an `Usuba_AST.prog` value 13 | - `-dump-steps-dir `: Directory in which each step should be dumped 14 | 15 | ### New script in `scripts`, `run-selected.sh`. 16 | 17 | Example use: 18 | 19 | `./run-selected.sh -- -dump-steps ast -dump-steps-dir tests/rsc` 20 | 21 | This will compute `usubac` with some user-provided arguments to a selected list of files that are currently: 22 | - `("ace.ua", "-V -interleave 2")` 23 | - `("aes_generic.ua", "-V")` 24 | - `("aes_mslice.ua", "-H")` 25 | - `("ascon.ua", "-V -interleave 2")` 26 | - `("rectangle.ua", "-H -interleave 2")` 27 | 28 | ## unit_tests [#30](https://github.com/usubalang/usuba/pull/30) 29 | 30 | See the [unit_tests repository](https://github.com/usubalang/unit_tests/commit/2cf99de7ea4b3a49841f14f5e0d40ff141885792). 31 | 32 | This repository is linked as a submodule in unit_tests and you shouldn't edit it. 33 | 34 | This submodule contains alcotest files for each directory in `unit_tests/rsc` allowing to create unit tests and execute them with `dune build @runtest`. These tests are used to check that refactoring passes does not brake their behaviour. 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Darius Mercadier 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean configure 2 | 3 | # Directories 4 | SRC_DIR := src 5 | BIN_DIR := bin 6 | SAMPLES_DIR := ../examples/samples 7 | DUNE := dune 8 | 9 | MAIN := main 10 | 11 | all: 12 | @if [ ! -f ./src/config.ml ]; then \ 13 | echo "config.ml was not found.";\ 14 | echo "./configure will be executed but you can/should rerun it if your directories are not located in the same places"; \ 15 | ./configure; \ 16 | fi 17 | @echo $(FILE_EXISTS) 18 | $(DUNE) build bin/cli/main.exe 19 | chmod +w _build/default/bin/cli/main.exe 20 | cp _build/default/bin/cli/main.exe usubac 21 | 22 | clean: 23 | rm -f *~ .*~ usubac 24 | $(DUNE) clean 25 | 26 | test: all 27 | ulimit -s unlimited 28 | @echo $(SAMPLES_DIR) 29 | dune build @runtest 30 | ./tests/test_parsing.sh --path $(SAMPLES_DIR) 31 | ./run_checks.pl --samples $(SAMPLES_DIR) 32 | 33 | unit-test: all 34 | dune build @runtest 35 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | 2 | - Add dir/m inference to type-checker 3 | - Make sure that functions that can't have the same input/output don't 4 | - Rewrite Unfold_unnest (in particular, temporaries in loops should have better types) 5 | - Rewrite Bitslice_shift 6 | - Rewrite Expand_array 7 | - Rewrite Utils: 8 | - split into multiple modules ? 9 | - clean code 10 | - Fix share_var 11 | - Fix Pre-schedule 12 | - Rewrite predicate to check is_usuba0 13 | - Make type-checker check if var is written twice 14 | - Add Present to checks 15 | 16 | - Major work: 17 | * automatically generate non-trivial vectorized code (Gimli, Chacha) 18 | * lower stack usage 19 | * efficient generation of Sboxes 20 | 21 | Expand_parameters / Monomorphize interaction issues 22 | 23 | 24 | node f' (a:um[4],a2:um'[3]) returns (b:um[4]) let b = a in 25 | node f' (a:u1[4],a2:u8[3]) returns (b:um[4],b2:um'[4]) let (b,b2) = (a,a2) in 26 | 27 | 28 | 29 | node f (a:um[4]) returns (b:um[4]) let b = a in 30 | 31 | - node f (a:u1[4]) returns (b:u1[4]) let b = a in 32 | - node f (a:u8[4]) returns (b:u8[4]) let b = a in 33 | 34 | node g (x:u4) returns (y:u4) let y = f(x[0],x[1],x[2],x[3]) tel 35 | node h (x:u8[4]) returns (y:u8[4]) let y = f(x) tel 36 | 37 | 38 | node f' (a:um[4],a2:um'[3]) returns (b:um[4]) let b = a in 39 | node k (x1:u4, x2:u8[3]) returns (y1:u4,y2:u8[3]) let (y1,y2) = f'(x1[0,1],x1[2,3],x2) tel 40 | 41 | a:um[4],a2:um'[3] 42 | x1[0,1]:u4[2],x1[2,3]:u4[2],x2:u8[3] 43 | 44 | 45 | ---- 46 | 47 | node f (a:um,a2:um') returns (b:u1[4]) let b = (a,a2) tel 48 | 49 | node g (x:u1[4]) returns (y:u1[4]) let y = f(x[0],x[1],x[2],x[3]) tel 50 | 51 | 52 | a_0,a_1,a2_0,a2_1 m=2,m'=2 53 | a_0,a_1,a_2,a2 m=3,m'=1 54 | a,a2_0,a2_1,a2_2 m=1,m'=3 55 | x[0],x[1],x[2],x[3] 56 | 57 | 58 | a, x, a' --> 1+2m 59 | x[0],x[1],x[2],x[3],x[4] --> 5 60 | 1+2m = 5 => m=2 61 | 62 | a, a' --> m+m' 63 | x[0],x[1],x[2],x[3],x[4] --> 5 64 | 65 | a:m, a':m' -> m+m' 66 | x:2,x2:1,x3:1 67 | 68 | 69 | ---- 70 | 71 | f(a:b1[4],b:b1[4]) ... 72 | 73 | 74 | x:b1[3] 75 | y:b1[3] 76 | z:b1[2] 77 | ... = f(x,y,z) 78 | 79 | 80 | ---- 81 | f(a:b1[4],b:b1[4]) ... 82 | 83 | g(...) returns (x:b1[3],y:b1[3],z:b1[2]) 84 | 85 | f( g(..) ) 86 | 87 | ---- 88 | node f (a:um,a2:um') returns (b:u1[4]) let b = (a,a2) tel 89 | node g (x:u1[4]) returns (y:u1[4]) let y = f(x[0],x[1],x[2],x[3]) tel 90 | 91 | m=2,m'=2 92 | void f(bool a[2],bool a2[2], bool b[4]) { 93 | b[0] = a[0]; 94 | b[1] = a[1]; 95 | b[2] = a2[0]; 96 | b[3] = a2[1]; 97 | } 98 | void h(int x[4],int y[4]) { 99 | int x1[2]; 100 | int x2[2]; 101 | x1[0] = x[0]; 102 | x1[1] = x[1]; 103 | x2[0] = x[2]; 104 | x2[1] = x[3]; 105 | f(x1,x2,y); 106 | } 107 | 108 | m=3,m'=1 109 | void f(bool a[3],bool a2[1], bool b[4]) { 110 | b[0] = a[0]; 111 | b[1] = a[1]; 112 | b[2] = a[2]; 113 | b[3] = a2[0]; 114 | } 115 | void h(int x[4],int y[4]) { 116 | int x1[3]; 117 | int x2[1]; 118 | x1[0] = x[0]; 119 | x1[1] = x[1]; 120 | x1[2] = x[2]; 121 | x2[0] = x[3]; 122 | f(x1,x2,y); 123 | } 124 | 125 | 126 | ---- 127 | 128 | node f(x:um[4],y:um[4],x':um'[4],y':um'[4]) returns (z:um[4],z:um'[4]) let 129 | forall i in [0,3] { 130 | z[i] = x[i] ^ y[i]; 131 | z'[i] = x'[i] ^ y'[i]; 132 | } 133 | tel 134 | 135 | 136 | f(a:u1[4],b:u1[4],a':u8[4],b':u8[4]) 137 | 138 | f(a:u1[4],b:u1[4],a':u8[2],a'':u8[2],b':u8[2],b'':u8[2]) 139 | 140 | 141 | f(x:u2[4],y:u2[4], 142 | 143 | 144 | x:um => x[0], x[1] 145 | 146 | 147 | 148 | ----- 149 | 150 | node f(a:v8) 151 | 152 | f(x:u4,y:u4) 153 | -------------------------------------------------------------------------------- /arch/FAME/.gitignore: -------------------------------------------------------------------------------- 1 | test_FAME -------------------------------------------------------------------------------- /arch/FAME/FAME.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* Configuration macros: 4 | 5 | - TI: the number of shares of the masking (1, 2, 4) 6 | 7 | - FD: the number of redundant slices (1, 2, 4) 8 | 9 | - PIPELINED: if defined, uses temporal redundancy 10 | 11 | - CORRECT: if defined, does fault correction by majority voting 12 | 13 | - X86: if defined, loads macros to execute on X86 (ie, without 14 | custom hardware) 15 | 16 | - NO_CUSTOM_INSTR: if defined, doesn't use custom instructions 17 | 18 | - GCC_SUPPORT: if defined, uses normal C instructions instead of 19 | custom ones, so that gcc can optimize them as it pleases. This 20 | simulates (ish) what would happen if we patched gcc to be aware 21 | of the semantics of our new instructions. 22 | 23 | - CHEATY_CUSTOM: if defined, uses normal assembly instructions 24 | instead of custom ones. This is just a trick to benchmark more 25 | realistic performances: the custom instructions are buggy 26 | (performance-wise) on the benchmark board, and using normal 27 | instruction instead gives more realistic performances. 28 | 29 | - COPROC_RAND: if defined, assumes the presence of a coprocessor 30 | generating 32 random bits every RANDOM_DELAY cycles. 31 | 32 | - RANDOM_DELAY: see COPROC_RAND 33 | 34 | - CST_RAND: if defined, assumes the presence of a coprocessor 35 | generating random bits faster than we consume them (ie, we can 36 | just read from a register without worrying ourselves with the 37 | availability of new random bytes). 38 | 39 | */ 40 | 41 | #ifndef BITS_PER_REG 42 | #define BITS_PER_REG 32 43 | #endif 44 | 45 | #ifndef DATATYPE 46 | #define DATATYPE unsigned int 47 | #endif 48 | 49 | #ifndef FD 50 | #error FD not defined (should be 1, 2 or 4) 51 | #endif 52 | 53 | #ifndef TI 54 | #error TI not defined (should be 1, 2 or 4) 55 | #endif 56 | 57 | #if FD != 4 && defined(CORRECT) 58 | #error Cannot use error correcting with FD != 4 59 | #endif 60 | 61 | #ifdef CORRECT 62 | #define MULT_CORRECT 1 63 | #else 64 | #define MULT_CORRECT 0 65 | #endif 66 | 67 | // Multiplication does fault checking by invoking FTCHK, which takes 68 | // an immediate as input, which describe which version of FTCHK to 69 | // call (this depends on FD). 70 | #if FD == 1 71 | #define IMM_FTCHK 0 /* no redundancy -> no fault check */ 72 | #elif FD == 2 73 | #define IMM_FTCHK 0b0011 74 | #elif FD == 4 && !defined(CORRECT) 75 | #define IMM_FTCHK 0b0101 76 | #elif FD == 4 && defined(CORRECT) 77 | #define IMM_FTCHK 0b11101 78 | #else 79 | #error Dunno know what IMM_FTCHK to use... 80 | #endif 81 | 82 | #if !defined(FD) || (FD == 1) 83 | #define SET_ALL_ONE() -1 84 | #define SET_ALL_ZERO() 0 85 | #elif FD == 2 86 | #define SET_ALL_ONE() 0x0000ffff 87 | #define SET_ALL_ZERO() 0xffff0000 88 | #elif FD == 4 89 | #define SET_ALL_ONE() 0x00ff00ff 90 | #define SET_ALL_ZERO() 0xff00ff00 91 | #endif 92 | 93 | #ifdef X86 94 | #include 95 | #include 96 | #endif 97 | 98 | extern int fault_flags; 99 | 100 | // loading custom instruction 101 | #include "FAME_instrs.h" 102 | 103 | // loading random 104 | #include "FAME_rand.h" 105 | 106 | // loading FD macros 107 | #include "FAME_FD.h" 108 | 109 | // loading TI macros 110 | #include "FAME_TI.h" 111 | 112 | 113 | // Finally defining AND/OR/XOR/NOT (which pretty much the only macros 114 | // used directly by AES). 115 | #define AND(a,b,c) TI_AND(a,b,c) /* a = b & c */ 116 | #define OR(a,b,c) TI_OR(a,b,c) /* a = b | c */ 117 | #define XOR(a,b,c) TI_XOR(a,b,c) /* a = b ^ c */ 118 | #define NOT(a,b) TI_NOT(a,b) /* a = ~b */ 119 | -------------------------------------------------------------------------------- /arch/FAME/FAME_FD.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* Will generate the macros FD_AND_x, FD_OR_x, FD_XOR_x, FD_NOT_x for 4 | x in 1, 2, 4, 5 | 6 | as well as FD_AND, FD_OR, FD_XOR and FD_NOT, which are the 7 | specialized versions of those macros for the currently defined FD. 8 | 9 | Uses the macros ANDC16, XORC16, ANDC8 and XORC8. 10 | */ 11 | 12 | #define FD_AND_1(r,a,b) (r) = (a) & (b) 13 | #define FD_OR_1(r,a,b) (r) = (a) | (b) 14 | #define FD_XOR_1(r,a,b) (r) = (a) ^ (b) 15 | #define FD_NOT_1(r,a) (r) = ~(a) 16 | 17 | #define FD_AND_2(r,a,b) ANDC16(r,a,b) 18 | #define FD_OR_2(r,a,b) { DATATYPE _tmp_or; ANDC16(_tmp_or,~a,~b); r = ~_tmp_or; } 19 | #define FD_XOR_2(r,a,b) XORC16(r,a,b) 20 | #define FD_NOT_2(r,a) (r) = ~(a) 21 | 22 | #define FD_AND_4(r,a,b) ANDC8(r,a,b) 23 | #define FD_OR_4(r,a,b) { DATATYPE _tmp_or; ANDC8(_tmp_or,~a,~b); r = ~_tmp_or; } 24 | #define FD_XOR_4(r,a,b) XORC8(r,a,b) 25 | #define FD_NOT_4(r,a) (r) = ~(a) 26 | 27 | #ifndef FD 28 | #define FD 1 29 | #endif 30 | 31 | #define _BUILD_OP_FD(OP,n) FD_ ## OP ## _ ## n 32 | #define BUILD_OP_FD(OP,n) _BUILD_OP_FD(OP,n) 33 | 34 | #define FD_AND BUILD_OP_FD(AND,FD) 35 | #define FD_OR BUILD_OP_FD(OR, FD) 36 | #define FD_XOR BUILD_OP_FD(XOR,FD) 37 | #define FD_NOT BUILD_OP_FD(NOT,FD) 38 | -------------------------------------------------------------------------------- /arch/FAME/Readme.md: -------------------------------------------------------------------------------- 1 | Custom headers for SKIVA backed 2 | --- 3 | 4 | ## TL;DR 5 | 6 | If you just need to run your SKIVA code, include `FAME.h` and define 7 | the following configuration macros: 8 | 9 | - `TI`: the number of shares of the masking (1, 2, 4) 10 | 11 | - `FD`: the number of redundant slices (1, 2, 4) 12 | 13 | - `PIPELINED`: if defined, uses temporal redundancy 14 | 15 | - `CORRECT`: if defined, does fault correction by majority voting 16 | 17 | - `X86`: if defined, loads macros to execute on X86 (ie, without 18 | custom hardware) 19 | 20 | - `NO_CUSTOM_INSTR`: if defined, doesn't use custom instructions 21 | 22 | - `GCC_SUPPORT`: if defined, uses normal C instructions instead of 23 | custom ones, so that gcc can optimize them as it pleases. This 24 | simulates (ish) what would happen if we patched gcc to be aware 25 | of the semantics of our new instructions. 26 | 27 | - `CHEATY_CUSTOM`: if defined, uses normal assembly instructions 28 | instead of custom ones. This is just a trick to benchmark more 29 | realistic performances: the custom instructions are buggy 30 | (performance-wise) on the benchmark board, and using normal 31 | instruction instead gives more realistic performances. 32 | 33 | - `COPROC_RAND`: if defined, assumes the presence of a coprocessor 34 | generating 32 random bits every `RANDOM_DELAY` cycles. 35 | 36 | - `RANDOM_DELAY`: see `COPROC_RAND` 37 | 38 | - `CST_RAND`: if defined, assumes the presence of a coprocessor 39 | generating random bits faster than we consume them (ie, we can 40 | just read from a register without worrying ourselves with the 41 | availability of new random bytes). 42 | 43 | 44 | ## Organization of the headers 45 | 46 | The headers are organized as follows. Note that the order in which 47 | each header is imported matters: `FAME_TI.h` relies on `FAME_rand.h` 48 | and `FAME_FD.h`, which relies on `FAME_instrs.h`. 49 | 50 | 51 | - `FAME.h`: the "entry point" header, load the other headers as 52 | needed, to eventually have the following macros defined: `AND`, 53 | `OR`, `NOT`, `XOR`, which are all you need to run AES. It also 54 | defines macros corresponding to all custom instructions (`SUBROT`, 55 | `FTCHK`, ...), as well as the `RAND` macro, and specific macros 56 | for each TI/FD (`TI_AND_2`, `TI_AND_4`, ...). 57 | 58 | - `FAME_instrs.h`: the "entry points" for the definition of the 59 | custom instructions. Depending on the configuration macros, this 60 | will either emulate them in software or use inline assembly to 61 | call the custom instructions. 62 | 63 | + `custom_instrs_soft.h`: defines the "advanced" custom 64 | instructions (TIBS, SUBROT, FTCHK) using software emulation. 65 | 66 | + `custom_instrs_hard.h`: defines the "advanced" custom 67 | instructions (TIBS, SUBROT, FTCHK) using inline assembly (and 68 | therefore produces code that calls the real instructions). 69 | 70 | - `FAME_rand.h`: defines the `RAND` macro. 71 | 72 | - `FAME_FD.h`: defines the macros `FD_AND_x`, `FD_OR_x`, `FD_XOR_x`, 73 | `FD_NOT_x` for x in 1, 2, 4. 74 | 75 | - `FAME_TI.h`: defines the macros `TI_AND_x`, `TI_OR_x`, `TI_XOR_x`, 76 | `TI_NOT_x` for x in 1, 2, 4. 77 | 78 | 79 | ## Testing 80 | 81 | You can test that the header `FAME.h` is correct by running 82 | `test_FAME.c`. This will test all the custom instructions for all 83 | values of FD and TI (1, 2, 4). To compile and run it on x86: 84 | 85 | clang -Wall -Wextra test_FAME.c -D TI=1 -D FD=1 -D X86 -o test_FAME 86 | ./test_FAME 87 | 88 | To compile it for SKIVA, you'd typically use our patch gaisler-gcc: 89 | 90 | sparc-gaisler-elf-gcc -Wall -Wextra test_FAME.c -D TI=1 -D FD=1 -o test_FAME 91 | 92 | And then load it on the board and run it. 93 | 94 | If everything works as expected, it should only print: 95 | 96 | Starting test. 97 | All right 98 | -------------------------------------------------------------------------------- /arch/FAME/custom_instrs_hard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* This file only contains "advanced" custom instructed, ie, all 4 | custom instructions but ANDCx, XORCx and XNORCx. 5 | 6 | */ 7 | 8 | 9 | #define TIBS(y,rd,r1,r2) { \ 10 | asm volatile("tibs %2, %3, %0\n\t" \ 11 | "mov %%y, %1\n\t" : "=r" (rd), "=r" (y) : "r" (r1), "r" (r2)); \ 12 | } 13 | /* r1/r2 are actually the destination, and rd/y the source 14 | but it makes it clearer to name them that way (since 15 | INVTIBS is the inverse of TIBS) */ 16 | #define INVTIBS(r2,r1,rd,y) { \ 17 | asm volatile("invtibs %2, %3, %0\n\t" \ 18 | "mov %%y, %1\n\t" : "=r" (r1), "=r" (r2) : "r" (rd), "r" (y)); \ 19 | } 20 | 21 | #define RED(r,y,i,a) { \ 22 | asm volatile("red %2, %3, %0\n\t" \ 23 | "mov %%y, %1\n\t" : "=r" (r), "=r" (y) : "r" (a), "i" (i)); \ 24 | } 25 | 26 | #define FTCHK(r,i,a) asm volatile("ftchk %1, %2, %0\n\t" : "=r" (r) : "r" (a), "i" (i) ); 27 | 28 | #define SUBROT_2(r,a) asm volatile("tibsrot %1, 2, %0\n\t" : "=r" (r) : "r" (a) :) 29 | #define SUBROT_4(r,a) asm volatile("tibsrot %1, 4, %0\n\t" : "=r" (r) : "r" (a) :) 30 | -------------------------------------------------------------------------------- /bin/cli/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name main) 3 | (public_name usuba) 4 | (package usuba) 5 | (libraries usuba_lib usuba_pp sexplib)) 6 | 7 | (env 8 | (dev 9 | (flags 10 | (:standard -warn-error -A)))) 11 | -------------------------------------------------------------------------------- /checks/correctness/ace/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef REF 7 | 8 | #include "ace.c" 9 | #define ace ace_permutation 10 | 11 | #elif defined(UA_V) 12 | 13 | #include "ace_ua_vslice.c" 14 | void ace(unsigned char text[40]) { 15 | uint32_t input[5][2]; 16 | for (int i = 0; i < 5; i++) 17 | for (int j = 0; j < 2; j++) 18 | input[i][j] = __builtin_bswap32(((uint32_t*)text)[i*2+j]); 19 | 20 | uint32_t output[5][2]; 21 | ACE__(input,output); 22 | for (int i = 0; i < 5; i++) 23 | for (int j = 0; j < 2; j++) 24 | ((uint32_t*)text)[i*2+j] = __builtin_bswap32(output[i][j]); 25 | } 26 | 27 | #elif defined(UA_B) 28 | 29 | #include "ace_ua_bitslice.c" 30 | /* Transposition stuffs */ 31 | static uint64_t mask_l[6] = { 32 | 0xaaaaaaaaaaaaaaaaUL, 33 | 0xccccccccccccccccUL, 34 | 0xf0f0f0f0f0f0f0f0UL, 35 | 0xff00ff00ff00ff00UL, 36 | 0xffff0000ffff0000UL, 37 | 0xffffffff00000000UL 38 | }; 39 | static uint64_t mask_r[6] = { 40 | 0x5555555555555555UL, 41 | 0x3333333333333333UL, 42 | 0x0f0f0f0f0f0f0f0fUL, 43 | 0x00ff00ff00ff00ffUL, 44 | 0x0000ffff0000ffffUL, 45 | 0x00000000ffffffffUL 46 | }; 47 | void transpose(uint64_t data[]) { 48 | for (int i = 0; i < 6; i ++) { 49 | int n = (1UL << i); 50 | for (int j = 0; j < 64; j += (2 * n)) 51 | for (int k = 0; k < n; k ++) { 52 | uint64_t u = data[j + k] & mask_l[i]; 53 | uint64_t v = data[j + k] & mask_r[i]; 54 | uint64_t x = data[j + n + k] & mask_l[i]; 55 | uint64_t y = data[j + n + k] & mask_r[i]; 56 | data[j + k] = u | (x >> n); 57 | data[j + n + k] = (v << n) | y; 58 | } 59 | } 60 | } 61 | 62 | void ace(unsigned char text[40]) { 63 | uint64_t text_bs[5][64]; 64 | for (int i = 0; i < 5; i++) { 65 | for (int j = 0; j < 64; j++) 66 | text_bs[i][j] = __builtin_bswap64(((uint64_t*)text)[i]); 67 | transpose(text_bs[i]); 68 | } 69 | 70 | uint64_t output_bs[5][64]; 71 | 72 | uint64_t (*input)[2][32] = (uint64_t (*)[2][32])text_bs; 73 | uint64_t (*output)[2][32] = (uint64_t (*)[2][32])output_bs; 74 | ACE__(input,output); 75 | 76 | for (int i = 0; i < 5; i++) { 77 | transpose(output_bs[i]); 78 | } 79 | 80 | for (int i = 0; i < 5; i++) 81 | ((uint64_t*)text)[i] = __builtin_bswap64(output_bs[i][0]); 82 | } 83 | 84 | 85 | #else 86 | #error Please define REF or UA_V 87 | #endif 88 | 89 | 90 | 91 | 92 | void test_ace() { 93 | 94 | // This seemigly random input is produced by encrypting full 0s plain 95 | unsigned char text[40] = { 96 | 0x5c, 0x93, 0x69, 0x1a, 0xd5, 0x06, 0x09, 0x35, 0xdc, 0x19, 97 | 0xce, 0x94, 0x7e, 0xad, 0x55, 0x0d, 0xac, 0x12, 0xbe, 0xe1, 98 | 0xa6, 0x4b, 0x67, 0x0e, 0xf5, 0x16, 0xe8, 0xbe, 0x1d, 0xfa, 99 | 0x60, 0xda, 0x40, 0x98, 0x92, 0xa4, 0xe4, 0xcc, 0xbc, 0x15 100 | }; 101 | 102 | ace(text); 103 | 104 | unsigned char expected[40] = { 105 | 0x9d, 0x27, 0x59, 0x7d, 0xaf, 0xa5, 0x50, 0x11, 0x22, 0x0c, 106 | 0x24, 0xa2, 0x36, 0xbe, 0x6e, 0x02, 0x8b, 0xe7, 0x20, 0xd3, 107 | 0x33, 0x51, 0x1e, 0xb1, 0x96, 0xc1, 0x53, 0x5e, 0xe1, 0x4f, 108 | 0x70, 0xc7, 0x2e, 0x5b, 0x33, 0xeb, 0xe5, 0x01, 0x01, 0x08 109 | }; 110 | 111 | if (memcmp(text, expected, 40) != 0) { 112 | fprintf(stderr, "Error encryption.\n"); 113 | fprintf(stderr, "Expected : "); 114 | for (int i = 0; i < 5; i++) { 115 | for (int j = 0; j < 8; j++) fprintf(stderr, "%02x",expected[i*8+j]); 116 | fprintf(stderr," "); 117 | } 118 | fprintf(stderr, "\nGot : "); 119 | for (int i = 0; i < 5; i++) { 120 | for (int j = 0; j < 8; j++) fprintf(stderr, "%02x",text[i*8+j]); 121 | fprintf(stderr," "); 122 | } 123 | fprintf(stderr, "\n"); 124 | exit(EXIT_FAILURE); 125 | } 126 | } 127 | 128 | 129 | int main() { 130 | test_ace(); 131 | } 132 | -------------------------------------------------------------------------------- /checks/correctness/aes/aes_ctr.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Crypt::Mode::CTR; 8 | 9 | my $key = pack 'H*', '2b7e151628aed2a6abf7158809cf4f3c'; 10 | my $iv = pack 'H*', 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff'; 11 | 12 | 13 | open my $FH, '<', 'input.txt'; 14 | 15 | local $/; 16 | my $plaintext = <$FH>; 17 | 18 | my $m = Crypt::Mode::CTR->new('AES',1); 19 | my $ciphertext = $m->encrypt($plaintext, $key, $iv); 20 | 21 | 22 | open $FH, '>', 'out_pl.txt' or die $!; 23 | print $FH $ciphertext; 24 | close $FH; 25 | -------------------------------------------------------------------------------- /checks/correctness/aes/avx/aes_bs.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define RUNTIME 9 | #define ORTHO 10 | #include "AVX.h" 11 | 12 | #include "aes.c" 13 | 14 | void aes_bs(DATATYPE plain[256], DATATYPE key[11][128], DATATYPE cipher[256]) { 15 | for (int i = 0; i < 256; i++) 16 | plain[i] = _mm256_shuffle_epi8(plain[i], 17 | _mm256_set_epi8(8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7, 18 | 8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7)); 19 | 20 | 21 | real_ortho_256x256(plain); 22 | 23 | AES__(plain,key,cipher); 24 | AES__(&plain[128],key,&cipher[128]); 25 | 26 | real_ortho_256x256(cipher); 27 | for (int i = 0; i < 256; i++) 28 | cipher[i] = _mm256_shuffle_epi8(cipher[i], 29 | _mm256_set_epi8(8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7, 30 | 8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7)); 31 | } 32 | -------------------------------------------------------------------------------- /checks/correctness/aes/avx/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_KEYBYTES 16 2 | #define CRYPTO_NONCEBYTES 16 3 | -------------------------------------------------------------------------------- /checks/correctness/aes/avx/crypto_stream.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usubalang/usuba/4553c25c3d8abd8bcbb2edf75740a3c6d0ca1222/checks/correctness/aes/avx/crypto_stream.h -------------------------------------------------------------------------------- /checks/correctness/aes/avx/key_sched.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* The only function of this file you shoud need: */ 7 | unsigned char* key_sched (const unsigned char in[16]); 8 | 9 | 10 | unsigned char sbox[256] = { 11 | 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 12 | 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 13 | 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 14 | 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 15 | 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 16 | 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 17 | 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 18 | 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 19 | 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 20 | 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 21 | 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 22 | 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 23 | 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 24 | 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 25 | 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 26 | 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 27 | 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 28 | 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 29 | 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 30 | 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 31 | 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 32 | 0xB0, 0x54, 0xBB, 0x16 33 | }; 34 | 35 | unsigned char rcon[11] = { 36 | 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 37 | }; 38 | 39 | void rotate(unsigned char* in) { 40 | unsigned char tmp = in[0]; 41 | for (int i = 0; i < 3; i++) 42 | in[i] = in[i+1]; 43 | in[3] = tmp; 44 | } 45 | 46 | void sched_core(unsigned char* in, unsigned int i) { 47 | rotate(in); 48 | for (int i = 0; i < 4; i++) 49 | in[i] = sbox[in[i]]; 50 | in[0] ^= rcon[i]; 51 | } 52 | 53 | unsigned char* key_sched (const unsigned char in[16]) { 54 | 55 | unsigned char* key = malloc(176 * sizeof(*key)); 56 | 57 | memcpy(key,in,16); 58 | int c = 16, i = 1; 59 | 60 | while (c < 176) { 61 | unsigned char tmp[4]; 62 | 63 | memcpy(tmp,&key[c-4],4); 64 | 65 | sched_core(tmp,i++); 66 | 67 | for (int k = 0; k < 4; k++) 68 | key[c+k] = key[c+k-16] ^ tmp[k]; 69 | c += 4; 70 | 71 | for (int j = 0; j < 3; j++) { 72 | memcpy(tmp,&key[c-4],4); 73 | for (int k = 0; k < 4; k++) 74 | key[c+k] = key[c+k-16] ^ tmp[k]; 75 | c += 4; 76 | } 77 | } 78 | 79 | return key; 80 | } 81 | -------------------------------------------------------------------------------- /checks/correctness/aes/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "stream.h" 6 | 7 | 8 | void test() { 9 | /* unsigned char key[16] = { 0 }; */ 10 | /* unsigned char iv[16] = { 0 }; */ 11 | unsigned char key[16] = { 0x54, 0x68, 0x61, 0x74, 0x73, 0x20, 0x6D, 0x79, 12 | 0x20, 0x4B, 0x75, 0x6E, 0x67, 0x20, 0x46, 0x75 }; 13 | unsigned char iv[16] = { 0x54, 0x77, 0x6F, 0x20, 0x4F, 0x6E, 0x65, 0x20, 14 | 0x4E, 0x69, 0x6E, 0x65, 0x20, 0x54, 0x77, 0x6F }; 15 | unsigned char input[16*64] = { 0 }; 16 | unsigned char output[16*64]; 17 | crypto_stream_xor(output,input,64*16,iv,key); 18 | for (int i = 0; i < 16; i++) { 19 | printf("%02x",output[i]); 20 | } 21 | } 22 | 23 | 24 | int main() { 25 | 26 | unsigned char key[16] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 27 | 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; 28 | unsigned char iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 29 | 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; 30 | 31 | FILE* fp_in = fopen("input.txt","rb"); 32 | FILE* fp_out = fopen("out_c.txt","wb"); 33 | 34 | fseek(fp_in, 0, SEEK_END); 35 | long fsize = ftell(fp_in); 36 | rewind(fp_in); 37 | 38 | unsigned char* input = aligned_alloc(32, fsize); 39 | unsigned char* output = aligned_alloc(32, fsize); 40 | fread(input, fsize, 1, fp_in); 41 | fclose(fp_in); 42 | 43 | crypto_stream_xor(output,input,fsize,iv,key); 44 | 45 | fwrite(output, fsize, 1, fp_out); 46 | fclose(fp_out); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /checks/correctness/aes/sse/aes_bs.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define RUNTIME 9 | #define ORTHO 10 | #include "SSE.h" 11 | 12 | #include "aes.c" 13 | 14 | void aes_bs(DATATYPE plain[128],DATATYPE key[11][128], DATATYPE cipher[128]) { 15 | for (int i = 0; i < 128; i++) 16 | plain[i] = _mm_shuffle_epi8(plain[i],_mm_set_epi8(8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7)); 17 | 18 | real_ortho_128x128(plain); 19 | 20 | AES__(plain,key,cipher); 21 | 22 | real_ortho_128x128(cipher); 23 | 24 | for (int i = 0; i < 128; i++) 25 | cipher[i] = _mm_shuffle_epi8(cipher[i],_mm_set_epi8(8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7)); 26 | } 27 | -------------------------------------------------------------------------------- /checks/correctness/aes/sse/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_KEYBYTES 16 2 | #define CRYPTO_NONCEBYTES 16 3 | -------------------------------------------------------------------------------- /checks/correctness/aes/sse/crypto_stream.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usubalang/usuba/4553c25c3d8abd8bcbb2edf75740a3c6d0ca1222/checks/correctness/aes/sse/crypto_stream.h -------------------------------------------------------------------------------- /checks/correctness/aes/sse/key_sched.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* The only function of this file you shoud need: */ 7 | unsigned char* key_sched (const unsigned char in[16]); 8 | 9 | 10 | unsigned char sbox[256] = { 11 | 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 12 | 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 13 | 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 14 | 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 15 | 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 16 | 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 17 | 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 18 | 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 19 | 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 20 | 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 21 | 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 22 | 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 23 | 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 24 | 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 25 | 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 26 | 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 27 | 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 28 | 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 29 | 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 30 | 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 31 | 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 32 | 0xB0, 0x54, 0xBB, 0x16 33 | }; 34 | 35 | unsigned char rcon[11] = { 36 | 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 37 | }; 38 | 39 | void rotate(unsigned char* in) { 40 | unsigned char tmp = in[0]; 41 | for (int i = 0; i < 3; i++) 42 | in[i] = in[i+1]; 43 | in[3] = tmp; 44 | } 45 | 46 | void sched_core(unsigned char* in, unsigned int i) { 47 | rotate(in); 48 | for (int i = 0; i < 4; i++) 49 | in[i] = sbox[in[i]]; 50 | in[0] ^= rcon[i]; 51 | } 52 | 53 | unsigned char* key_sched (const unsigned char in[16]) { 54 | 55 | unsigned char* key = malloc(176 * sizeof(*key)); 56 | 57 | memcpy(key,in,16); 58 | int c = 16, i = 1; 59 | 60 | while (c < 176) { 61 | unsigned char tmp[4]; 62 | 63 | memcpy(tmp,&key[c-4],4); 64 | 65 | sched_core(tmp,i++); 66 | 67 | for (int k = 0; k < 4; k++) 68 | key[c+k] = key[c+k-16] ^ tmp[k]; 69 | c += 4; 70 | 71 | for (int j = 0; j < 3; j++) { 72 | memcpy(tmp,&key[c-4],4); 73 | for (int k = 0; k < 4; k++) 74 | key[c+k] = key[c+k-16] ^ tmp[k]; 75 | c += 4; 76 | } 77 | } 78 | 79 | return key; 80 | } 81 | -------------------------------------------------------------------------------- /checks/correctness/aes/std/aes_bs.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define RUNTIME 9 | #define ORTHO 10 | #include "STD.h" 11 | 12 | #include "aes.c" 13 | 14 | 15 | void aes_bs(DATATYPE plain[128],DATATYPE key[11][128], DATATYPE cipher[128]) { 16 | for (int i = 0; i < 128; i++) 17 | plain[i] = __builtin_bswap64(plain[i]); 18 | 19 | orthogonalize(plain,plain); 20 | orthogonalize(&plain[64],&plain[64]); 21 | 22 | DATATYPE tmp[128]; 23 | AES__(plain,key,tmp); 24 | 25 | orthogonalize(tmp,tmp); 26 | orthogonalize(&tmp[64],&tmp[64]); 27 | 28 | for (int i = 0; i < 128; i++) 29 | tmp[i] = __builtin_bswap64(tmp[i]); 30 | 31 | for (int i = 0; i < 64; i++) { 32 | cipher[i*2] = tmp[i]; 33 | cipher[i*2+1] = tmp[i+64]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /checks/correctness/aes/std/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_KEYBYTES 16 2 | #define CRYPTO_NONCEBYTES 16 3 | -------------------------------------------------------------------------------- /checks/correctness/aes/std/crypto_stream.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usubalang/usuba/4553c25c3d8abd8bcbb2edf75740a3c6d0ca1222/checks/correctness/aes/std/crypto_stream.h -------------------------------------------------------------------------------- /checks/correctness/aes/std/key_sched.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* The only function of this file you shoud need: */ 7 | unsigned char* key_sched (const unsigned char in[16]); 8 | 9 | 10 | unsigned char sbox[256] = { 11 | 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 12 | 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 13 | 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 14 | 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 15 | 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 16 | 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 17 | 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 18 | 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 19 | 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 20 | 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 21 | 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 22 | 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 23 | 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 24 | 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 25 | 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 26 | 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 27 | 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 28 | 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 29 | 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 30 | 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 31 | 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 32 | 0xB0, 0x54, 0xBB, 0x16 33 | }; 34 | 35 | unsigned char rcon[11] = { 36 | 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 37 | }; 38 | 39 | void rotate(unsigned char* in) { 40 | unsigned char tmp = in[0]; 41 | for (int i = 0; i < 3; i++) 42 | in[i] = in[i+1]; 43 | in[3] = tmp; 44 | } 45 | 46 | void sched_core(unsigned char* in, unsigned int i) { 47 | rotate(in); 48 | for (int i = 0; i < 4; i++) 49 | in[i] = sbox[in[i]]; 50 | in[0] ^= rcon[i]; 51 | } 52 | 53 | unsigned char* key_sched (const unsigned char in[16]) { 54 | 55 | unsigned char* key = malloc(176 * sizeof(*key)); 56 | 57 | memcpy(key,in,16); 58 | int c = 16, i = 1; 59 | 60 | while (c < 176) { 61 | unsigned char tmp[4]; 62 | 63 | memcpy(tmp,&key[c-4],4); 64 | 65 | sched_core(tmp,i++); 66 | 67 | for (int k = 0; k < 4; k++) 68 | key[c+k] = key[c+k-16] ^ tmp[k]; 69 | c += 4; 70 | 71 | for (int j = 0; j < 3; j++) { 72 | memcpy(tmp,&key[c-4],4); 73 | for (int k = 0; k < 4; k++) 74 | key[c+k] = key[c+k-16] ^ tmp[k]; 75 | c += 4; 76 | } 77 | } 78 | 79 | return key; 80 | } 81 | -------------------------------------------------------------------------------- /checks/correctness/aes/stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int crypto_stream_xor( unsigned char *out, 4 | const unsigned char *in, 5 | unsigned long long inlen, 6 | const unsigned char *n, 7 | const unsigned char *k 8 | ); 9 | -------------------------------------------------------------------------------- /checks/correctness/aes_mslice/aes.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; use warnings; 4 | use v5.14; 5 | 6 | use Crypt::Mode::ECB; 7 | 8 | open my $FH, '<', 'input.txt'; 9 | 10 | local $/; 11 | my $plaintext = <$FH>; 12 | 13 | my $key = "0123456789ABCDEF"; 14 | my $ecb = Crypt::Mode::ECB->new('AES',0); 15 | my $ciphertext = $ecb->encrypt($plaintext, $key); 16 | 17 | open $FH, '>', 'out.txt' or die $!; 18 | print $FH $ciphertext; 19 | close $FH; 20 | -------------------------------------------------------------------------------- /checks/correctness/aes_mslice/input.txt: -------------------------------------------------------------------------------- 1 | ABCDEFGHIJKLMNOP0123456789ABCDEFAZERTYUIOPQSDFGHNBVCXWMLKJHGFDSQ01234567890123459876543210987654ABCXYZABCXYZABCXA0B1C2D3E4F5G6H7 2 | -------------------------------------------------------------------------------- /checks/correctness/aes_mslice/key_sched.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* The only function of this file you shoud need: */ 7 | char* key_sched (char in[16]); 8 | 9 | 10 | unsigned char sbox[256] = { 11 | 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 12 | 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 13 | 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 14 | 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 15 | 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 16 | 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 17 | 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 18 | 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 19 | 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 20 | 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 21 | 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 22 | 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 23 | 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 24 | 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 25 | 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 26 | 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 27 | 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 28 | 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 29 | 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 30 | 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 31 | 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 32 | 0xB0, 0x54, 0xBB, 0x16 33 | }; 34 | 35 | unsigned char rcon[11] = { 36 | 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 37 | }; 38 | 39 | void rotate(unsigned char* in) { 40 | unsigned char tmp = in[0]; 41 | for (int i = 0; i < 3; i++) 42 | in[i] = in[i+1]; 43 | in[3] = tmp; 44 | } 45 | 46 | void sched_core(unsigned char* in, unsigned int i) { 47 | rotate(in); 48 | for (int i = 0; i < 4; i++) 49 | in[i] = sbox[in[i]]; 50 | in[0] ^= rcon[i]; 51 | } 52 | 53 | char* key_sched (char in[16]) { 54 | 55 | char* key = malloc(176 * sizeof(*key)); 56 | 57 | memcpy(key,in,16); 58 | int c = 16, i = 1; 59 | 60 | while (c < 176) { 61 | unsigned char tmp[4]; 62 | 63 | memcpy(tmp,&key[c-4],4); 64 | 65 | sched_core(tmp,i++); 66 | 67 | for (int k = 0; k < 4; k++) 68 | key[c+k] = key[c+k-16] ^ tmp[k]; 69 | c += 4; 70 | 71 | for (int j = 0; j < 3; j++) { 72 | memcpy(tmp,&key[c-4],4); 73 | for (int k = 0; k < 4; k++) 74 | key[c+k] = key[c+k-16] ^ tmp[k]; 75 | c += 4; 76 | } 77 | } 78 | 79 | return key; 80 | } 81 | -------------------------------------------------------------------------------- /checks/correctness/ascon/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef REF 7 | 8 | #include "ascon_ref.c" 9 | #define ascon(x) P12((state*)x) 10 | 11 | #elif defined(UA_V) 12 | 13 | #include "ascon_ua_vslice.c" 14 | void ascon(uint64_t text[5]) { 15 | uint64_t output[5]; 16 | ascon12__(text,output); 17 | memcpy(text,output,5*sizeof(uint64_t)); 18 | } 19 | 20 | #elif defined(UA_B) 21 | #include "ascon_ua_bitslice.c" 22 | /* Transposition stuffs */ 23 | static uint64_t mask_l[6] = { 24 | 0xaaaaaaaaaaaaaaaaUL, 25 | 0xccccccccccccccccUL, 26 | 0xf0f0f0f0f0f0f0f0UL, 27 | 0xff00ff00ff00ff00UL, 28 | 0xffff0000ffff0000UL, 29 | 0xffffffff00000000UL 30 | }; 31 | static uint64_t mask_r[6] = { 32 | 0x5555555555555555UL, 33 | 0x3333333333333333UL, 34 | 0x0f0f0f0f0f0f0f0fUL, 35 | 0x00ff00ff00ff00ffUL, 36 | 0x0000ffff0000ffffUL, 37 | 0x00000000ffffffffUL 38 | }; 39 | void transpose(uint64_t data[]) { 40 | for (int i = 0; i < 6; i ++) { 41 | int n = (1UL << i); 42 | for (int j = 0; j < 64; j += (2 * n)) 43 | for (int k = 0; k < n; k ++) { 44 | uint64_t u = data[j + k] & mask_l[i]; 45 | uint64_t v = data[j + k] & mask_r[i]; 46 | uint64_t x = data[j + n + k] & mask_l[i]; 47 | uint64_t y = data[j + n + k] & mask_r[i]; 48 | data[j + k] = u | (x >> n); 49 | data[j + n + k] = (v << n) | y; 50 | } 51 | } 52 | } 53 | 54 | void ascon(uint64_t text[5]) { 55 | uint64_t text_bs[5][64]; 56 | for (int i = 0; i < 5; i++) { 57 | for (int j = 0; j < 64; j++) 58 | text_bs[i][j] = text[i]; 59 | transpose(text_bs[i]); 60 | } 61 | 62 | uint64_t output_bs[5][64]; 63 | ascon12__(text_bs,output_bs); 64 | 65 | for (int i = 0; i < 5; i++) { 66 | transpose(output_bs[i]); 67 | } 68 | 69 | for (int i = 0; i < 5; i++) 70 | text[i] = output_bs[i][0];//__builtin_bswap64(output_bs[i*64]); 71 | } 72 | 73 | #else 74 | #error Please define REF or UA_V 75 | #endif 76 | 77 | 78 | 79 | 80 | void test_ascon() { 81 | 82 | // This seemigly random input is produced by encrypting full 0s plain 83 | uint64_t text[5] = { 0x78ea7ae5cfebb108, 0x9b9bfb8513b560f7, 0x6937f83e03d11a50, 84 | 0x3fe53f36f2c1178c, 0x045d648e4def12c9 }; 85 | //uint64_t text[5] = { 0, 0, 0, 0, 0 }; 86 | 87 | ascon(text); 88 | 89 | uint64_t expected[5] = { 0x0e87fa7d4b40022e, 0x94f14f2525499af5, 0x30a1d1621866701c, 90 | 0x4b419cf3ae4c9962, 0xb11ce0a087175b71 }; 91 | 92 | if (memcmp(text, expected, 5*sizeof(uint64_t)) != 0) { 93 | fprintf(stderr, "Error encryption.\n"); 94 | fprintf(stderr, "Expected : "); 95 | for (int i = 0; i < 5; i++) fprintf(stderr, "%016lx ",expected[i]); 96 | fprintf(stderr, "\nGot : "); 97 | for (int i = 0; i < 5; i++) fprintf(stderr, "%016lx ",text[i]); 98 | fprintf(stderr, "\n"); 99 | exit(EXIT_FAILURE); 100 | } 101 | } 102 | 103 | 104 | int main() { 105 | test_ascon(); 106 | } 107 | -------------------------------------------------------------------------------- /checks/correctness/chacha20/AVX/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_KEYBYTES 32 2 | #define CRYPTO_NONCEBYTES 8 3 | -------------------------------------------------------------------------------- /checks/correctness/chacha20/SSE/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_KEYBYTES 32 2 | #define CRYPTO_NONCEBYTES 8 3 | -------------------------------------------------------------------------------- /checks/correctness/chacha20/STD/STD.h: -------------------------------------------------------------------------------- 1 | /* ******************************************** *\ 2 | * 3 | * 4 | * 5 | \* ******************************************** */ 6 | 7 | 8 | /* Including headers */ 9 | #pragma once 10 | #include 11 | #include 12 | 13 | 14 | #ifndef BITS_PER_REG 15 | #define BITS_PER_REG 64 16 | #endif 17 | #ifndef LOG2_BITS_PER_REG 18 | #define LOG2_BITS_PER_REG 6 19 | #endif 20 | 21 | /* Defining macros */ 22 | #define REG_SIZE BITS_PER_REG 23 | #define CHUNK_SIZE 64 24 | 25 | #define AND(a,b) ((a) & (b)) 26 | #define OR(a,b) ((a) | (b)) 27 | #define XOR(a,b) ((a) ^ (b)) 28 | #define ANDN(a,b) (~(a) & (b)) 29 | #define NOT(a) (~(a)) 30 | 31 | #define ADD(a,b,c) ((a) + (b)) 32 | 33 | #define L_SHIFT(a,b,c) ((a) << (b)) 34 | #define R_SHIFT(a,b,c) ((a) >> (b)) 35 | #define L_ROTATE(a,b,c) ((a << b) | (a >> (c-b))) 36 | #define R_ROTATE(a,b,c) ((a >> b) | (a << (c-b))) 37 | 38 | 39 | #ifndef DATATYPE 40 | #if BITS_PER_REG == 32 41 | #define DATATYPE unsigned int 42 | #else 43 | #define DATATYPE uint64_t 44 | #endif 45 | #endif 46 | 47 | #define SET_ALL_ONE() -1 48 | #define SET_ALL_ZERO() 0 49 | 50 | #define ORTHOGONALIZE(in,out) orthogonalize(in,out) 51 | #define UNORTHOGONALIZE(in,out) unorthogonalize(in,out) 52 | 53 | #define ALLOC(size) malloc(size * sizeof(uint64_t)) 54 | 55 | 56 | 57 | #ifndef NO_RUNTIME 58 | 59 | 60 | /* Orthogonalization stuffs */ 61 | static uint64_t mask_l[6] = { 62 | 0xaaaaaaaaaaaaaaaaUL, 63 | 0xccccccccccccccccUL, 64 | 0xf0f0f0f0f0f0f0f0UL, 65 | 0xff00ff00ff00ff00UL, 66 | 0xffff0000ffff0000UL, 67 | 0xffffffff00000000UL 68 | }; 69 | 70 | static uint64_t mask_r[6] = { 71 | 0x5555555555555555UL, 72 | 0x3333333333333333UL, 73 | 0x0f0f0f0f0f0f0f0fUL, 74 | 0x00ff00ff00ff00ffUL, 75 | 0x0000ffff0000ffffUL, 76 | 0x00000000ffffffffUL 77 | }; 78 | 79 | 80 | void real_ortho(uint64_t data[]) { 81 | for (int i = 0; i < 6; i ++) { 82 | int n = (1UL << i); 83 | for (int j = 0; j < 64; j += (2 * n)) 84 | for (int k = 0; k < n; k ++) { 85 | uint64_t u = data[j + k] & mask_l[i]; 86 | uint64_t v = data[j + k] & mask_r[i]; 87 | uint64_t x = data[j + n + k] & mask_l[i]; 88 | uint64_t y = data[j + n + k] & mask_r[i]; 89 | data[j + k] = u | (x >> n); 90 | data[j + n + k] = (v << n) | y; 91 | } 92 | } 93 | } 94 | 95 | #ifdef ORTHO 96 | 97 | void orthogonalize(uint64_t* data, uint64_t* out) { 98 | for (int i = 0; i < 64; i++) 99 | out[i] = data[i]; 100 | real_ortho(out); 101 | } 102 | 103 | void unorthogonalize(uint64_t *in, uint64_t* data) { 104 | for (int i = 0; i < 64; i++) 105 | data[i] = in[i]; 106 | real_ortho(data); 107 | } 108 | 109 | #else 110 | 111 | void orthogonalize(uint64_t* data, uint64_t* out) { 112 | for (int i = 0; i < 64; i++) 113 | out[i] = data[i]; 114 | } 115 | 116 | void unorthogonalize(uint64_t *in, uint64_t* data) { 117 | for (int i = 0; i < 64; i++) 118 | data[i] = in[i]; 119 | } 120 | 121 | 122 | #endif /* ORTHO */ 123 | 124 | #endif /* NO_RUNTIME */ 125 | -------------------------------------------------------------------------------- /checks/correctness/chacha20/STD/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_KEYBYTES 32 2 | #define CRYPTO_NONCEBYTES 8 3 | -------------------------------------------------------------------------------- /checks/correctness/chacha20/crypto_stream.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usubalang/usuba/4553c25c3d8abd8bcbb2edf75740a3c6d0ca1222/checks/correctness/chacha20/crypto_stream.h -------------------------------------------------------------------------------- /checks/correctness/chacha20/main_verif.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "stream.h" 6 | 7 | #define SIZE 512 8 | 9 | int test() { 10 | unsigned char key[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 11 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 12 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 13 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; 14 | unsigned char nonce[8] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; 15 | 16 | 17 | unsigned char out[SIZE] = { 0 }; 18 | crypto_stream(out,SIZE,nonce,key); 19 | 20 | unsigned char res[512] = { 21 | 0xf7,0x98,0xa1,0x89,0xf1,0x95,0xe6,0x69,0x82,0x10,0x5f,0xfb,0x64,0x0b,0xb7,0x75, 22 | 0x7f,0x57,0x9d,0xa3,0x16,0x02,0xfc,0x93,0xec,0x01,0xac,0x56,0xf8,0x5a,0xc3,0xc1, 23 | 0x34,0xa4,0x54,0x7b,0x73,0x3b,0x46,0x41,0x30,0x42,0xc9,0x44,0000,0x49,0x17,0x69, 24 | 0x05,0xd3,0xbe,0x59,0xea,0x1c,0x53,0xf1,0x59,0x16,0x15,0x5c,0x2b,0xe8,0x24,0x1a, 25 | 0x38,0000,0x8b,0x9a,0x26,0xbc,0x35,0x94,0x1e,0x24,0x44,0x17,0x7c,0x8a,0xde,0x66, 26 | 0x89,0xde,0x95,0x26,0x49,0x86,0xd9,0x58,0x89,0xfb,0x60,0xe8,0x46,0x29,0xc9,0xbd, 27 | 0x9a,0x5a,0xcb,0x1c,0xc1,0x18,0xbe,0x56,0x3e,0xb9,0xb3,0xa4,0xa4,0x72,0xf8,0x2e, 28 | 0x09,0xa7,0xe7,0x78,0x49,0x2b,0x56,0x2e,0xf7,0x13,0x0e,0x88,0xdf,0xe0,0x31,0xc7, 29 | 0x9d,0xb9,0xd4,0xf7,0xc7,0xa8,0x99,0x15,0x1b,0x9a,0x47,0x50,0x32,0xb6,0x3f,0xc3, 30 | 0x85,0x24,0x5f,0xe0,0x54,0xe3,0xdd,0x5a,0x97,0xa5,0xf5,0x76,0xfe,0x06,0x40,0x25, 31 | 0xd3,0xce,0x04,0x2c,0x56,0x6a,0xb2,0xc5,0x07,0xb1,0x38,0xdb,0x85,0x3e,0x3d,0x69, 32 | 0x59,0x66,0x09,0x96,0x54,0x6c,0xc9,0xc4,0xa6,0xea,0xfd,0xc7,0x77,0xc0,0x40,0xd7, 33 | 0x0e,0xaf,0x46,0xf7,0x6d,0xad,0x39,0x79,0xe5,0xc5,0x36,0x0c,0x33,0x17,0x16,0x6a, 34 | 0x1c,0x89,0x4c,0x94,0xa3,0x71,0x87,0x6a,0x94,0xdf,0x76,0x28,0xfe,0x4e,0xaa,0xf2, 35 | 0xcc,0xb2,0x7d,0x5a,0xaa,0xe0,0xad,0x7a,0xd0,0xf9,0xd4,0xb6,0xad,0x3b,0x54,0x09, 36 | 0x87,0x46,0xd4,0x52,0x4d,0x38,0x40,0x7a,0x6d,0xeb,0x3a,0xb7,0x8f,0xab,0x78,0xc9, 37 | 0x42,0x13,0x66,0x8b,0xbb,0xd3,0x94,0xc5,0xde,0x93,0xb8,0x53,0x17,0x8a,0xdd,0xd6, 38 | 0xb9,0x7f,0x9f,0xa1,0xec,0x3e,0x56,0xc0,0x0c,0x9d,0xdf,0xf0,0xa4,0x4a,0x20,0x42, 39 | 0x41,0x17,0x5a,0x4c,0xab,0x0f,0x96,0x1b,0xa5,0x3e,0xde,0x9b,0xdf,0x96,0x0b,0x94, 40 | 0xf9,0x82,0x9b,0x1f,0x34,0x14,0x72,0x64,0x29,0xb3,0x62,0xc5,0xb5,0x38,0xe3,0x91, 41 | 0x52,0x0f,0x48,0x9b,0x7e,0xd8,0xd2,0x0a,0xe3,0xfd,0x49,0xe9,0xe2,0x59,0xe4,0x43, 42 | 0x97,0x51,0x4d,0x61,0x8c,0x96,0xc4,0x84,0x6b,0xe3,0xc6,0x80,0xbd,0xc1,0x1c,0x71, 43 | 0xdc,0xbb,0xe2,0x9c,0xcf,0x80,0xd6,0x2a,0x09,0x38,0xfa,0x54,0x93,0x91,0xe6,0xea, 44 | 0x57,0xec,0xbe,0x26,0x06,0x79,0x0e,0xc1,0x5d,0x22,0x24,0xae,0x30,0x7c,0x14,0x42, 45 | 0x26,0xb7,0xc4,0xe8,0xc2,0xf9,0x7d,0x2a,0x1d,0x67,0x85,0x2d,0x29,0xbe,0xba,0x11, 46 | 0x0e,0xdd,0x44,0x51,0x97,0x01,0x20,0x62,0xa3,0x93,0xa9,0xc9,0x28,0x03,0xad,0x3b, 47 | 0x4f,0x31,0xd7,0xbc,0x60,0x33,0xcc,0xf7,0x93,0x2c,0xfe,0xd3,0xf0,0x19,0x04,0x4d, 48 | 0x25,0x90,0x59,0x16,0x77,0x72,0x86,0xf8,0x2f,0x9a,0x4c,0xc1,0xff,0xe4,0x30,0xff, 49 | 0xd1,0xdc,0xfc,0x27,0xde,0xed,0x32,0x7b,0x9f,0x96,0x30,0xd2,0xfa,0x96,0x9f,0xb6, 50 | 0xf0,0x60,0x3c,0xd1,0x9d,0xd9,0xa9,0x51,0x9e,0x67,0x3b,0xcf,0xcd,0x90,0x14,0x12, 51 | 0x52,0x91,0xa4,0x46,0x69,0xef,0x72,0x85,0xe7,0x4e,0xd3,0x72,0x9b,0x67,0x7f,0x80, 52 | 0x1c,0x3c,0xdf,0x05,0x8c,0x50,0x96,0x31,0x68,0xb4,0x96,0x04,0x37,0x16,0xc7,0x30 }; 53 | 54 | int result = 0; 55 | 56 | if (memcmp(out,res,SIZE) != 0) { 57 | fprintf(stderr,"Error crypto_stream().\n"); 58 | result = 1; 59 | } 60 | 61 | crypto_stream_xor(out,res,SIZE,nonce,key); 62 | 63 | memset(res,0,SIZE); 64 | 65 | if (memcmp(out,res,SIZE) != 0) { 66 | fprintf(stderr,"Error crypto_stream_xor().\n"); 67 | result = 1; 68 | } 69 | 70 | return result; 71 | } 72 | 73 | 74 | int main() { 75 | 76 | return test(); 77 | } 78 | -------------------------------------------------------------------------------- /checks/correctness/chacha20/stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int crypto_stream_xor( unsigned char *out, 4 | const unsigned char *in, 5 | unsigned long long inlen, 6 | const unsigned char *n, 7 | const unsigned char *k 8 | ); 9 | 10 | 11 | int crypto_stream(unsigned char *out, 12 | unsigned long long outlen, 13 | const unsigned char *n, 14 | const unsigned char *k 15 | ); 16 | -------------------------------------------------------------------------------- /checks/correctness/check_ace.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | 15 | sub error { 16 | say "************ ERROR **************\n\n"; 17 | exit 1; 18 | } 19 | 20 | use require::relative "../../subroutines.pl"; 21 | 22 | my $samples = samples_location(); 23 | 24 | # Compiling the compiler. 25 | unless ($ARGV[0]) { 26 | say "Compiling..."; 27 | error if system 'make'; 28 | } 29 | 30 | for my $slicing ('vslice', 'bitslice') { 31 | my $temp_dir = "tmp_ace_$slicing"; 32 | 33 | say "############################# Ace $slicing ############################"; 34 | 35 | # switching to usuba dir 36 | chdir "$FindBin::Bin/../.."; 37 | 38 | # Switching to temporary directory. 39 | say "Preparing the files for the test..."; 40 | remove_tree $temp_dir if -d $temp_dir; 41 | mkdir $temp_dir; 42 | 43 | # Compiling Usuba Clyde. 44 | say "Compiling Ace from Usuba to C..."; 45 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B'; 46 | error if system "./usubac $slicing_flag -o $temp_dir/ace_ua_$slicing.c -arch std $samples/usuba/ace.ua"; 47 | 48 | chdir $temp_dir; 49 | copy $_, "." for glob "$FindBin::Bin/ace/*"; 50 | 51 | # Compiling the C files 52 | say "Compiling the test executable..."; 53 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 54 | error if system "clang -D $implem_flag -march=native -I../arch -I . -o main main.c"; 55 | 56 | say "Running the test..."; 57 | error if system './main'; 58 | 59 | chdir '..'; 60 | remove_tree $temp_dir; 61 | 62 | say "$slicing Ace OK.\n\n"; 63 | } 64 | -------------------------------------------------------------------------------- /checks/correctness/check_ace_masked.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | use lib $FindBin::Bin; 14 | 15 | use require::relative "../../subroutines.pl"; 16 | 17 | my $samples = samples_location(); 18 | 19 | sub error { 20 | say "************ ERROR **************\n\n"; 21 | exit 1; 22 | } 23 | 24 | # Compiling the compiler. 25 | unless ($ARGV[0]) { 26 | say "Compiling..."; 27 | error if system 'make'; 28 | } 29 | 30 | for my $slicing ('vslice', 'bitslice') { 31 | my $temp_dir = "tmp_ace_masked_$slicing"; 32 | 33 | say "############################# Ace-masked $slicing ############################"; 34 | 35 | # switching to usuba dir 36 | chdir "$FindBin::Bin/../.."; 37 | 38 | # Switching to temporary directory. 39 | say "Preparing the files for the test..."; 40 | remove_tree $temp_dir if -d $temp_dir; 41 | mkdir $temp_dir; 42 | 43 | # Compiling Usuba Clyde. 44 | say "Compiling Ace-Masked from Usuba to C..."; 45 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B'; 46 | error if system "./usubac -ua-masked $slicing_flag -o $temp_dir/ace_ua_$slicing.c -arch std -no-sched $samples/usuba/ace.ua"; 47 | 48 | chdir $temp_dir; 49 | copy $_, "." for glob "$FindBin::Bin/ace_masked/*"; 50 | 51 | # Compiling the C files 52 | say "Compiling the test executable..."; 53 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 54 | error if system "clang -D $implem_flag -D MASKING_ORDER=4 -march=native -I../arch -I . -o main main.c"; 55 | 56 | say "Running the test..."; 57 | error if system './main'; 58 | 59 | chdir '..'; 60 | remove_tree $temp_dir; 61 | 62 | say "$slicing Ace-masked OK.\n\n"; 63 | } 64 | -------------------------------------------------------------------------------- /checks/correctness/check_aes.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(dircopy fcopy rcopy); 11 | use FindBin; 12 | 13 | sub error { 14 | say "************ ERROR **************\n\n"; 15 | exit 1; 16 | } 17 | 18 | use require::relative "../../subroutines.pl"; 19 | 20 | my $samples = samples_location(); 21 | 22 | my $temp_dir = "tmp_aes"; 23 | 24 | say "############################## Bitslice AES ###########################"; 25 | 26 | # switching to usuba dir 27 | chdir "$FindBin::Bin/../.."; 28 | 29 | # Compiling the compiler. 30 | unless ($ARGV[0]) { 31 | say "Compiling..."; 32 | error if system 'make'; 33 | } 34 | 35 | 36 | # Switching to temporary directory. 37 | say "Preparing the files for the test..."; 38 | remove_tree $temp_dir if -d $temp_dir; 39 | mkdir $temp_dir; 40 | chdir $temp_dir; 41 | 42 | dircopy "$FindBin::Bin/aes/$_", $_ for qw(std sse avx); 43 | copy $_, "." for glob "$FindBin::Bin/aes/{main.c,stream.h,aes_ctr.pl}"; 44 | 45 | chdir ".."; 46 | say "Compiling AES from Usuba to C..."; 47 | for my $arch (qw(std sse avx)) { 48 | error if system "./usubac -B -o $temp_dir/$arch/aes.c -arch $arch -no-share -no-sched $samples/usuba/aes.ua" ; 49 | } 50 | 51 | chdir $temp_dir; 52 | 53 | 54 | for my $ARCH (qw(std sse avx)) { 55 | # Compiling the C files 56 | say "Compiling the test executable with $ARCH..."; 57 | error if system "clang -Wall -Wextra -march=native -I../arch -o aes main.c $ARCH/stream.c"; 58 | 59 | say "Running the test with $ARCH..."; 60 | error if system 'head -c 8M input.txt'; 61 | error if system 'perl aes_ctr.pl'; 62 | error if system './aes'; 63 | 64 | error if system 'cmp --silent out_c.txt out_pl.txt'; 65 | unlink 'out_c.txt', 'out_pl.txt'; 66 | } 67 | 68 | chdir '..'; 69 | remove_tree $temp_dir; 70 | 71 | say "Bitsliced AES OK.\n\n"; 72 | -------------------------------------------------------------------------------- /checks/correctness/check_aes_mslice.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use FindBin; 11 | 12 | sub error { 13 | say "************ ERROR **************\n\n"; 14 | exit 1; 15 | } 16 | 17 | use require::relative "../../subroutines.pl"; 18 | 19 | my $samples = samples_location(); 20 | 21 | my $temp_dir = "tmp_aes_mslice"; 22 | 23 | say "############################### AES Mslice ############################"; 24 | 25 | # switching to usuba dir 26 | chdir "$FindBin::Bin/../.."; 27 | 28 | # Compiling the compiler. 29 | unless ($ARGV[0]) { 30 | say "Compiling..."; 31 | error if system 'make'; 32 | } 33 | 34 | 35 | # Switching to temporary directory. 36 | say "Preparing the files for the test..."; 37 | remove_tree $temp_dir if -d $temp_dir; 38 | mkdir $temp_dir; 39 | 40 | # Compiling Usuba AES. 41 | say "Compiling AES from Usuba to C..."; 42 | error if system "./usubac -H -o $temp_dir/aes.c -arch sse -no-share $samples/usuba/aes_mslice.ua" ; 43 | { 44 | local $^I = ""; 45 | local @ARGV = "$temp_dir/aes.c"; 46 | while(<>) { 47 | s/#include .*//; 48 | } continue { print } 49 | } 50 | 51 | 52 | chdir $temp_dir; 53 | copy $_, '.' for glob "$FindBin::Bin/aes_mslice/*"; 54 | 55 | 56 | for my $ARCH (qw(AVX SSE)) { 57 | # Compiling the C files 58 | say "Compiling the test executable with $ARCH..."; 59 | error if system "clang -D $ARCH -march=native -I../arch -o aes main.c"; 60 | 61 | say "Running the test with $ARCH..."; 62 | error if system 'head -c 8M input.txt'; 63 | error if system 'perl aes.pl'; 64 | error if system './aes'; 65 | 66 | error if system 'cmp --silent output.txt out.txt'; 67 | unlink 'output.txt', 'out.txt'; 68 | } 69 | 70 | chdir '..'; 71 | remove_tree $temp_dir; 72 | 73 | say "n-sliced AES OK.\n\n"; 74 | -------------------------------------------------------------------------------- /checks/correctness/check_ascon.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | 15 | sub error { 16 | say "************ ERROR **************\n\n"; 17 | exit 1; 18 | } 19 | 20 | use require::relative "../../subroutines.pl"; 21 | 22 | my $samples = samples_location(); 23 | 24 | # Compiling the compiler. 25 | unless ($ARGV[0]) { 26 | say "Compiling..."; 27 | error if system 'make'; 28 | } 29 | 30 | for my $slicing ('vslice', 'bitslice') { 31 | my $temp_dir = "tmp_ascon_$slicing"; 32 | 33 | say "############################# Ascon $slicing ############################"; 34 | 35 | # switching to usuba dir 36 | chdir "$FindBin::Bin/../.."; 37 | 38 | # Switching to temporary directory. 39 | say "Preparing the files for the test..."; 40 | remove_tree $temp_dir if -d $temp_dir; 41 | mkdir $temp_dir; 42 | 43 | # Compiling Usuba Clyde. 44 | say "Compiling Ascon from Usuba to C..."; 45 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B'; 46 | error if system "./usubac $slicing_flag -o $temp_dir/ascon_ua_$slicing.c -arch std -no-sched $samples/usuba/ascon.ua"; 47 | 48 | chdir $temp_dir; 49 | copy $_, "." for glob "$FindBin::Bin/ascon/*"; 50 | 51 | # Compiling the C files 52 | say "Compiling the test executable..."; 53 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 54 | error if system "clang -D $implem_flag -march=native -I../arch -I . -o main main.c"; 55 | 56 | say "Running the test..."; 57 | error if system './main'; 58 | 59 | chdir '..'; 60 | remove_tree $temp_dir; 61 | 62 | say "$slicing Ascon OK.\n\n"; 63 | } 64 | -------------------------------------------------------------------------------- /checks/correctness/check_ascon_masked.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | 15 | use require::relative "../../subroutines.pl"; 16 | 17 | my $samples = samples_location(); 18 | 19 | sub error { 20 | say "************ ERROR **************\n\n"; 21 | exit 1; 22 | } 23 | 24 | # Compiling the compiler. 25 | unless ($ARGV[0]) { 26 | say "Compiling..."; 27 | error if system 'make'; 28 | } 29 | 30 | for my $slicing ('vslice', 'bitslice') { 31 | my $temp_dir = "tmp_ascon_masked_$slicing"; 32 | 33 | say "############################# Ascon-masked $slicing ############################"; 34 | 35 | # switching to usuba dir 36 | chdir "$FindBin::Bin/../.."; 37 | 38 | # Switching to temporary directory. 39 | say "Preparing the files for the test..."; 40 | remove_tree $temp_dir if -d $temp_dir; 41 | mkdir $temp_dir; 42 | 43 | # Compiling Usuba Clyde. 44 | say "Compiling Ascon from Usuba to C..."; 45 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B'; 46 | error if system "./usubac -ua-masked $slicing_flag -o $temp_dir/ascon_ua_$slicing.c -arch std -no-sched $samples/usuba/ascon.ua"; 47 | 48 | chdir $temp_dir; 49 | copy $_, "." for glob "$FindBin::Bin/ascon_masked/*"; 50 | 51 | # Compiling the C files 52 | say "Compiling the test executable..."; 53 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 54 | error if system "clang -D $implem_flag -D MASKING_ORDER=4 -march=native -I../arch -I . -o main main.c"; 55 | 56 | say "Running the test..."; 57 | error if system './main'; 58 | 59 | chdir '..'; 60 | remove_tree $temp_dir; 61 | 62 | say "$slicing Ascon-masked OK.\n\n"; 63 | } 64 | -------------------------------------------------------------------------------- /checks/correctness/check_chacha20.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | my $temp_dir = "tmp_chacha20"; 24 | 25 | say "################################ Chacha20 ##############################"; 26 | 27 | # switching to usuba dir 28 | chdir "$FindBin::Bin/../.."; 29 | 30 | # Compiling the compiler. 31 | unless ($ARGV[0]) { 32 | say "Compiling..."; 33 | error if system 'make'; 34 | } 35 | 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba DES. 43 | say "Compiling Chacha20 from Usuba to C..."; 44 | error if system "./usubac -V -o $temp_dir/chacha20.c -arch sse -no-share $samples/usuba/chacha20.ua" ; 45 | { 46 | local $^I = ""; 47 | local @ARGV = "$temp_dir/chacha20.c"; 48 | while(<>) { 49 | s/#include .*//; 50 | } continue { print } 51 | } 52 | 53 | chdir $temp_dir; 54 | copy $_, "." for glob "$FindBin::Bin/chacha20/{main_verif.c,stream.h,crypto_stream.h}"; 55 | #rcopy $_, '.' for glob "$FindBin::Bin/chacha20/*"; 56 | 57 | for my $ARCH (qw(STD SSE AVX)) { 58 | dircopy "$FindBin::Bin/chacha20/$ARCH/", "."; 59 | copy "chacha20.c", "$ARCH/"; 60 | # Compiling the C files 61 | say "Compiling the test executable with $ARCH..."; 62 | error if system "clang -march=native -I../arch -I . -o chacha20 main_verif.c $ARCH/stream.c"; 63 | 64 | say "Running the test with $ARCH..."; 65 | error if system './chacha20'; 66 | } 67 | 68 | chdir '..'; 69 | remove_tree $temp_dir; 70 | 71 | say "Vsliced Chacha20 OK.\n\n"; 72 | -------------------------------------------------------------------------------- /checks/correctness/check_clyde_bitslice.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | my $temp_dir = "tmp_clyde_bitslice"; 24 | 25 | say "############################ Clyde Bitslice ###########################"; 26 | 27 | # switching to usuba dir 28 | chdir "$FindBin::Bin/../.."; 29 | 30 | # Compiling the compiler. 31 | unless ($ARGV[0]) { 32 | say "Compiling..."; 33 | error if system 'make'; 34 | } 35 | 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Clyde from Usuba to C..."; 44 | error if system "./usubac -B -o $temp_dir/clyde.c -arch std -no-share $samples/usuba/clyde.ua" ; 45 | 46 | chdir $temp_dir; 47 | copy $_, "." for glob "$FindBin::Bin/clyde/*"; 48 | 49 | for my $ARCH (qw(STD)) { 50 | # Compiling the C files 51 | say "Compiling the test executable with $ARCH..."; 52 | error if system "clang -D UA_B -march=native -I../arch -I . -o main main.c"; 53 | 54 | say "Running the test with $ARCH..."; 55 | error if system './main'; 56 | } 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "Bitsliced Clyde OK.\n\n"; 62 | -------------------------------------------------------------------------------- /checks/correctness/check_clyde_masked.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | for my $slicing (qw(bitslice vslice)) { 24 | my $temp_dir = "tmp_clyde_masked_$slicing"; 25 | 26 | say "############################ Clyde-masked $slicing ###########################"; 27 | 28 | # switching to usuba dir 29 | chdir "$FindBin::Bin/../.."; 30 | 31 | # Compiling the compiler. 32 | unless ($ARGV[0]) { 33 | say "Compiling..."; 34 | error if system 'make'; 35 | } 36 | 37 | 38 | # Switching to temporary directory. 39 | say "Preparing the files for the test..."; 40 | remove_tree $temp_dir if -d $temp_dir; 41 | mkdir $temp_dir; 42 | 43 | # Compiling Usuba Clyde. 44 | say "Compiling Clyde-masked from Usuba to C..."; 45 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B'; 46 | error if system "./usubac -ua-masked $slicing_flag -o $temp_dir/clyde_ua_$slicing.c -arch std -no-share $samples/usuba/clyde.ua" ; 47 | 48 | chdir $temp_dir; 49 | copy $_, "." for glob "$FindBin::Bin/clyde_masked/*"; 50 | 51 | for my $ARCH (qw(STD)) { 52 | # Compiling the C files 53 | say "Compiling the test executable with $ARCH..."; 54 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 55 | error if system "clang -D $implem_flag -D MASKING_ORDER=4 -march=native -I../arch -I . -o main main.c"; 56 | 57 | say "Running the test with $ARCH..."; 58 | error if system './main'; 59 | } 60 | 61 | chdir '..'; 62 | remove_tree $temp_dir; 63 | 64 | say "$slicing Clyde-masked OK.\n\n"; 65 | } 66 | -------------------------------------------------------------------------------- /checks/correctness/check_clyde_vslice.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | my $temp_dir = "tmp_clyde_vslice"; 24 | 25 | say "############################# Clyde Vslice ############################"; 26 | 27 | # switching to usuba dir 28 | chdir "$FindBin::Bin/../.."; 29 | 30 | # Compiling the compiler. 31 | unless ($ARGV[0]) { 32 | say "Compiling..."; 33 | error if system 'make'; 34 | } 35 | 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Clyde from Usuba to C..."; 44 | error if system "./usubac -V -o $temp_dir/clyde.c -arch std -no-share $samples/usuba/clyde.ua" ; 45 | 46 | chdir $temp_dir; 47 | copy $_, "." for glob "$FindBin::Bin/clyde/*"; 48 | 49 | for my $ARCH (qw(STD)) { 50 | # Compiling the C files 51 | say "Compiling the test executable with $ARCH..."; 52 | error if system "clang -D UA_V -march=native -I../arch -I . -o main main.c"; 53 | 54 | say "Running the test with $ARCH..."; 55 | error if system './main'; 56 | } 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "Bitsliced Clyde OK.\n\n"; 62 | -------------------------------------------------------------------------------- /checks/correctness/check_des.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use FindBin; 11 | 12 | use require::relative "../../subroutines.pl"; 13 | 14 | my $samples = samples_location(); 15 | 16 | sub error { 17 | say "************ ERROR **************\n\n"; 18 | exit 1; 19 | } 20 | 21 | my $temp_dir = "tmp_des"; 22 | 23 | say "################################## DES ################################"; 24 | 25 | # switching to usuba dir 26 | chdir "$FindBin::Bin/../.."; 27 | 28 | # Compiling the compiler. 29 | unless ($ARGV[0]) { 30 | say "Compiling..."; 31 | error if system 'make'; 32 | } 33 | 34 | 35 | # Switching to temporary directory. 36 | say "Preparing the files for the test..."; 37 | remove_tree $temp_dir if -d $temp_dir; 38 | mkdir $temp_dir; 39 | 40 | # Compiling Usuba DES. 41 | say "Regenerating the DES code..."; 42 | error if system "./usubac -no-arr -B -o $temp_dir/des.c -arch avx $samples/usuba/des.ua" ; 43 | { 44 | local $^I = ""; 45 | local @ARGV = "$temp_dir/des.c"; 46 | while(<>) { 47 | s/#include .*//; 48 | } continue { print } 49 | } 50 | 51 | chdir $temp_dir; 52 | copy $_, '.' for glob "$FindBin::Bin/des/*"; 53 | 54 | 55 | error if system 'clang -march=native -o des_ref ref_usuba.c'; 56 | 57 | 58 | for my $ARCH (qw(STD SSE AVX)) { 59 | # Compiling the C files 60 | say "Compiling the test executable..."; 61 | error if system "clang -D $ARCH -march=native -I../arch -o des_to_test main.c"; 62 | 63 | say "Running the test with $ARCH..."; 64 | error if system 'head -c 8M input.txt'; 65 | error if system './des_ref'; 66 | error if system './des_to_test'; 67 | 68 | error if system 'cmp --silent output.txt output_to_test.txt'; 69 | unlink "output.txt output_to_test.txt" 70 | } 71 | 72 | chdir '..'; 73 | remove_tree $temp_dir; 74 | 75 | say "Bitslice DES OK.\n\n"; 76 | -------------------------------------------------------------------------------- /checks/correctness/check_drygascon.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | # Compiling the compiler. 24 | unless ($ARGV[0]) { 25 | say "Compiling..."; 26 | error if system 'make'; 27 | } 28 | 29 | for my $slicing ('vslice', 'bitslice') { 30 | my $temp_dir = "tmp_drygascon_$slicing"; 31 | 32 | say "############################# Drygascon $slicing ############################"; 33 | 34 | # switching to usuba dir 35 | chdir "$FindBin::Bin/../.."; 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Drygascon from Usuba to C..."; 44 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B'; 45 | error if system "./usubac -light-inline $slicing_flag -o $temp_dir/drygascon_ua_$slicing.c -arch std -no-sched $samples/usuba/drygascon.ua"; 46 | 47 | chdir $temp_dir; 48 | copy $_, "." for glob "$FindBin::Bin/drygascon/*"; 49 | 50 | # Compiling the C files 51 | say "Compiling the test executable..."; 52 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 53 | error if system "clang -D $implem_flag -march=native -I../arch -I . -o main main.c"; 54 | 55 | say "Running the test..."; 56 | error if system './main'; 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "$slicing Drygascon OK.\n\n"; 62 | } 63 | -------------------------------------------------------------------------------- /checks/correctness/check_gift.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | # Compiling the compiler. 24 | unless ($ARGV[0]) { 25 | say "Compiling..."; 26 | error if system 'make'; 27 | } 28 | 29 | for my $slicing ('vslice', 'bitslice') { 30 | my $temp_dir = "tmp_gift_$slicing"; 31 | 32 | say "############################# Gift $slicing ############################"; 33 | 34 | # switching to usuba dir 35 | chdir "$FindBin::Bin/../.."; 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Gift from Usuba to C..."; 44 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B'; 45 | my $special_ua = $slicing eq 'bitslice' ? '_bitslice' : ''; 46 | error if system "./usubac $slicing_flag -o $temp_dir/gift_ua_$slicing.c -arch std -no-sched $samples/usuba/gift${special_ua}.ua"; 47 | 48 | chdir $temp_dir; 49 | copy $_, "." for glob "$FindBin::Bin/gift/*"; 50 | 51 | # Compiling the C files 52 | say "Compiling the test executable..."; 53 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 54 | error if system "clang -Wno-incompatible-pointer-types -D $implem_flag -march=native -I../arch -I . -o main main.c"; 55 | 56 | say "Running the test..."; 57 | error if system './main'; 58 | 59 | chdir '..'; 60 | remove_tree $temp_dir; 61 | 62 | say "$slicing Gift OK.\n\n"; 63 | } 64 | -------------------------------------------------------------------------------- /checks/correctness/check_gimli_bitslice.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | my $temp_dir = "tmp_gimli_bitslice"; 24 | 25 | say "############################ Gimli Bitslice ###########################"; 26 | 27 | # switching to usuba dir 28 | chdir "$FindBin::Bin/../.."; 29 | 30 | # Compiling the compiler. 31 | unless ($ARGV[0]) { 32 | say "Compiling..."; 33 | error if system 'make'; 34 | } 35 | 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Gimli. 43 | say "Compiling Gimli from Usuba to C..."; 44 | error if system "./usubac -B -inline-all -o $temp_dir/gimli.c -arch std -no-share $samples/usuba/gimli_bitslice.ua" ; 45 | 46 | chdir $temp_dir; 47 | copy $_, "." for glob "$FindBin::Bin/gimli/*"; 48 | 49 | for my $ARCH (qw(STD)) { 50 | # Compiling the C files 51 | say "Compiling the test executable with $ARCH..."; 52 | error if system "clang -D UA_B -Wno-incompatible-pointer-types -march=native -I../arch -I . -o main main.c"; 53 | 54 | say "Running the test with $ARCH..."; 55 | error if system './main'; 56 | } 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "Bitsliced Gimli OK.\n\n"; 62 | -------------------------------------------------------------------------------- /checks/correctness/check_gimli_masked.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | for my $slicing ('vslice', 'bitslice') { 24 | my $temp_dir = "tmp_gimli_masked_$slicing"; 25 | 26 | say "############################ Gimli-masked $slicing ###########################"; 27 | 28 | # switching to usuba dir 29 | chdir "$FindBin::Bin/../.."; 30 | 31 | # Compiling the compiler. 32 | unless ($ARGV[0]) { 33 | say "Compiling..."; 34 | error if system 'make'; 35 | } 36 | 37 | 38 | # Switching to temporary directory. 39 | say "Preparing the files for the test..."; 40 | remove_tree $temp_dir if -d $temp_dir; 41 | mkdir $temp_dir; 42 | 43 | # Compiling Usuba Gimli. 44 | say "Compiling Gimli from Usuba to C..."; 45 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B -inline-all'; 46 | my $file_end = $slicing eq 'vslice' ? '' : '_bitslice'; 47 | error if system "./usubac -light-inline -ua-masked $slicing_flag -o $temp_dir/gimli_ua_$slicing.c -arch std -no-share $samples/usuba/gimli$file_end.ua" ; 48 | 49 | chdir $temp_dir; 50 | copy $_, "." for glob "$FindBin::Bin/gimli_masked/*"; 51 | 52 | # Compiling the C files 53 | say "Compiling the test executable..."; 54 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 55 | error if system "clang -D $implem_flag -D MASKING_ORDER=4 -Wno-incompatible-pointer-types -march=native -I../arch -I . -o main main.c"; 56 | 57 | say "Running the test..."; 58 | error if system './main'; 59 | 60 | chdir '..'; 61 | remove_tree $temp_dir; 62 | 63 | say "$slicing Gimli-masked OK.\n\n"; 64 | } 65 | -------------------------------------------------------------------------------- /checks/correctness/check_gimli_vslice.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | my $temp_dir = "tmp_gimli_vslice"; 24 | 25 | say "############################# Gimli Vslice ############################"; 26 | 27 | # switching to usuba dir 28 | chdir "$FindBin::Bin/../.."; 29 | 30 | # Compiling the compiler. 31 | unless ($ARGV[0]) { 32 | say "Compiling..."; 33 | error if system 'make'; 34 | } 35 | 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Gimli. 43 | say "Compiling Gimli from Usuba to C..."; 44 | error if system "./usubac -V -o $temp_dir/gimli.c -arch std -no-share $samples/usuba/gimli.ua" ; 45 | 46 | chdir $temp_dir; 47 | copy $_, "." for glob "$FindBin::Bin/gimli/*"; 48 | 49 | for my $ARCH (qw(STD)) { 50 | # Compiling the C files 51 | say "Compiling the test executable with $ARCH..."; 52 | error if system "clang -D UA_V -Wno-incompatible-pointer-types -march=native -I../arch -I . -o main main.c"; 53 | 54 | say "Running the test with $ARCH..."; 55 | error if system './main'; 56 | } 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "Bitsliced Gimli OK.\n\n"; 62 | -------------------------------------------------------------------------------- /checks/correctness/check_photon.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | # Compiling the compiler. 24 | unless ($ARGV[0]) { 25 | say "Compiling..."; 26 | error if system 'make'; 27 | } 28 | 29 | for my $slicing ('vslice', 'bitslice') { 30 | my $temp_dir = "tmp_photon_$slicing"; 31 | 32 | say "############################# Photon $slicing ############################"; 33 | 34 | # switching to usuba dir 35 | chdir "$FindBin::Bin/../.."; 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Photon from Usuba to C..."; 44 | my $slicing_flag = $slicing eq 'vslice' ? '-V -keep-tables' : '-B'; 45 | error if system "./usubac $slicing_flag -o $temp_dir/photon_ua_$slicing.c -arch std -no-sched $samples/usuba/photon_$slicing.ua"; 46 | 47 | chdir $temp_dir; 48 | copy $_, "." for glob "$FindBin::Bin/photon/*"; 49 | 50 | # Compiling the C files 51 | say "Compiling the test executable..."; 52 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 53 | error if system "clang -D $implem_flag -march=native -I../arch -I . -o main main.c"; 54 | 55 | say "Running the test..."; 56 | error if system './main'; 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "$slicing Photon OK.\n\n"; 62 | } 63 | -------------------------------------------------------------------------------- /checks/correctness/check_pyjamask.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | 24 | for my $slicing ('bitslice', 'vslice') { 25 | 26 | my $temp_dir = "tmp_pyjamask_$slicing"; 27 | 28 | say "############################ Pyjamask $slicing ###########################"; 29 | 30 | # switching to usuba dir 31 | chdir "$FindBin::Bin/../.."; 32 | 33 | # Compiling the compiler. 34 | unless ($ARGV[0]) { 35 | say "Compiling..."; 36 | error if system 'make'; 37 | } 38 | 39 | 40 | # Switching to temporary directory. 41 | say "Preparing the files for the test..."; 42 | remove_tree $temp_dir if -d $temp_dir; 43 | mkdir $temp_dir; 44 | 45 | # Compiling Usuba DES. 46 | say "Compiling Pyjamask from Usuba to C..."; 47 | my $slicing_flag = $slicing eq 'bitslice' ? '-B' : '-V'; 48 | error if system "./usubac $slicing_flag -o $temp_dir/pyjamask_ua_$slicing.c -arch std -no-share -no-sched $samples/usuba/pyjamask_$slicing.ua" ; 49 | 50 | chdir $temp_dir; 51 | copy $_, "." for glob "$FindBin::Bin/pyjamask/*"; 52 | 53 | for my $ARCH (qw(STD)) { 54 | # Compiling the C files 55 | say "Compiling the test executable with $ARCH..."; 56 | my $slicing_flag = $slicing eq 'bitslice' ? 'UA_B' : 'UA_V'; 57 | error if system "clang -Wno-incompatible-pointer-types -march=native -I../arch -I . -o main -D $slicing_flag main.c"; 58 | 59 | say "Running the test with $ARCH..."; 60 | error if system './main'; 61 | } 62 | 63 | chdir '..'; 64 | remove_tree $temp_dir; 65 | 66 | say ucfirst "$slicing Pyjamask OK.\n\n"; 67 | } 68 | -------------------------------------------------------------------------------- /checks/correctness/check_pyjamask_masked.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | 24 | for my $slicing ('bitslice', 'vslice') { 25 | 26 | my $temp_dir = "tmp_pyjamask_masked_$slicing"; 27 | 28 | say "############################ Pyjamask-masked $slicing ###########################"; 29 | 30 | # switching to usuba dir 31 | chdir "$FindBin::Bin/../.."; 32 | 33 | # Compiling the compiler. 34 | unless ($ARGV[0]) { 35 | say "Compiling..."; 36 | error if system 'make'; 37 | } 38 | 39 | 40 | # Switching to temporary directory. 41 | say "Preparing the files for the test..."; 42 | remove_tree $temp_dir if -d $temp_dir; 43 | mkdir $temp_dir; 44 | 45 | # Compiling Usuba DES. 46 | say "Compiling Pyjamask-masked from Usuba to C..."; 47 | my $slicing_flag = $slicing eq 'bitslice' ? '-B' : '-V'; 48 | error if system "./usubac -ua-masked -light-inline $slicing_flag -o $temp_dir/pyjamask_ua_$slicing.c -arch std -no-share -no-sched $samples/usuba/pyjamask_$slicing.ua" ; 49 | 50 | chdir $temp_dir; 51 | copy $_, "." for glob "$FindBin::Bin/pyjamask_masked/*"; 52 | 53 | for my $ARCH (qw(STD)) { 54 | # Compiling the C files 55 | say "Compiling the test executable with $ARCH..."; 56 | my $slicing_flag = $slicing eq 'bitslice' ? 'UA_B' : 'UA_V'; 57 | error if system "clang -march=native -I../arch -I . -o main -D $slicing_flag -D MASKING_ORDER=4 main.c"; 58 | say "Running the test with $ARCH..."; 59 | error if system './main'; 60 | } 61 | 62 | chdir '..'; 63 | remove_tree $temp_dir; 64 | 65 | say ucfirst "$slicing Pyjamask-masked OK.\n\n"; 66 | } 67 | -------------------------------------------------------------------------------- /checks/correctness/check_serpent.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use FindBin; 11 | 12 | use require::relative "../../subroutines.pl"; 13 | 14 | my $samples = samples_location(); 15 | 16 | sub error { 17 | say "************ ERROR **************\n\n"; 18 | exit 1; 19 | } 20 | 21 | my $temp_dir = "tmp_serpent"; 22 | 23 | say "################################ Serpent ##############################"; 24 | 25 | # switching to usuba dir 26 | chdir "$FindBin::Bin/../.."; 27 | 28 | # Compiling the compiler. 29 | unless ($ARGV[0]) { 30 | say "Compiling..."; 31 | error if system 'make'; 32 | } 33 | 34 | 35 | # Switching to temporary directory. 36 | say "Preparing the files for the test..."; 37 | remove_tree $temp_dir if -d $temp_dir; 38 | mkdir $temp_dir; 39 | 40 | # Compiling Usuba DES. 41 | say "Compiling Serpent from Usuba to C..."; 42 | error if system "./usubac -V -o $temp_dir/serpent.c -arch sse -no-share $samples/usuba/serpent.ua" ; 43 | { 44 | local $^I = ""; 45 | local @ARGV = "$temp_dir/serpent.c"; 46 | while(<>) { 47 | s/#include .*//; 48 | } continue { print } 49 | } 50 | 51 | chdir $temp_dir; 52 | copy $_, '.' for glob "$FindBin::Bin/serpent/*"; 53 | 54 | # Compiling the reference implementation 55 | say "Compiling reference C implementation..."; 56 | error if system 'clang -march=native -I../arch -o serpent_ref ref.c'; 57 | 58 | for my $ARCH (qw(STD SSE AVX)) { 59 | # Compiling the C files 60 | say "Compiling the test executable with $ARCH..."; 61 | error if system "clang -D $ARCH -march=native -I../arch -o serpent main.c"; 62 | 63 | say "Running the test with $ARCH..."; 64 | error if system 'head -c 8M input.txt'; 65 | error if system './serpent_ref'; 66 | error if system './serpent'; 67 | 68 | error if system 'cmp --silent output.txt out.txt'; 69 | unlink 'output.txt', 'out.txt'; 70 | } 71 | 72 | chdir '..'; 73 | remove_tree $temp_dir; 74 | 75 | say "n-sliced Serpent OK.\n\n"; 76 | -------------------------------------------------------------------------------- /checks/correctness/check_skinny_bitslice.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | my $temp_dir = "tmp_skinny_bitslice"; 24 | 25 | say "############################# Skinny Bitslice ############################"; 26 | 27 | # switching to usuba dir 28 | chdir "$FindBin::Bin/../.."; 29 | 30 | # Compiling the compiler. 31 | unless ($ARGV[0]) { 32 | say "Compiling..."; 33 | error if system 'make'; 34 | } 35 | 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Skinny from Usuba to C..."; 44 | error if system "./usubac -B -o $temp_dir/skinny_ua_bitslice.c -arch std -no-share $samples/usuba/skinny_bitslice.ua"; 45 | 46 | chdir $temp_dir; 47 | copy $_, "." for glob "$FindBin::Bin/skinny/*"; 48 | 49 | for my $ARCH (qw(STD)) { 50 | # Compiling the C files 51 | say "Compiling the test executable with $ARCH..."; 52 | error if system "clang -D UA_B -march=native -I../arch -I . -o main main.c"; 53 | 54 | say "Running the test with $ARCH..."; 55 | error if system './main'; 56 | } 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "Bitsliced Skinny OK.\n\n"; 62 | -------------------------------------------------------------------------------- /checks/correctness/check_skinny_vslice.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | my $temp_dir = "tmp_skinny_vslice"; 24 | 25 | say "############################# Skinny Vslice ############################"; 26 | 27 | # switching to usuba dir 28 | chdir "$FindBin::Bin/../.."; 29 | 30 | # Compiling the compiler. 31 | unless ($ARGV[0]) { 32 | say "Compiling..."; 33 | error if system 'make'; 34 | } 35 | 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Skinny from Usuba to C..."; 44 | error if system "./usubac -keep-tables -V -o $temp_dir/skinny_ua_vslice.c -arch std -no-share $samples/usuba/skinny_vslice.ua"; 45 | 46 | chdir $temp_dir; 47 | copy $_, "." for glob "$FindBin::Bin/skinny/*"; 48 | 49 | for my $ARCH (qw(STD)) { 50 | # Compiling the C files 51 | say "Compiling the test executable with $ARCH..."; 52 | error if system "clang -D UA_V -march=native -I../arch -I . -o main main.c"; 53 | 54 | say "Running the test with $ARCH..."; 55 | error if system './main'; 56 | } 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "Vslice Skinny OK.\n\n"; 62 | -------------------------------------------------------------------------------- /checks/correctness/check_spongent.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | # Compiling the compiler. 24 | unless ($ARGV[0]) { 25 | say "Compiling..."; 26 | error if system 'make'; 27 | } 28 | 29 | for my $slicing ('bitslice') { 30 | my $temp_dir = "tmp_spongent_$slicing"; 31 | 32 | say "############################# Spongent $slicing ############################"; 33 | 34 | # switching to usuba dir 35 | chdir "$FindBin::Bin/../.."; 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Spongent from Usuba to C..."; 44 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B'; 45 | error if system "./usubac $slicing_flag -light-inline -bits-per-reg 32 -o $temp_dir/spongent_ua_$slicing.c -arch std -no-sched $samples/usuba/spongent.ua"; 46 | 47 | chdir $temp_dir; 48 | copy $_, "." for glob "$FindBin::Bin/spongent/*"; 49 | 50 | # Compiling the C files 51 | say "Compiling the test executable..."; 52 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 53 | error if system "clang -D $implem_flag -march=native -I../arch -I . -o main main.c"; 54 | 55 | say "Running the test..."; 56 | error if system './main'; 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "$slicing Spongent OK.\n\n"; 62 | } 63 | -------------------------------------------------------------------------------- /checks/correctness/check_subterranean.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | # Compiling the compiler. 24 | unless ($ARGV[0]) { 25 | say "Compiling..."; 26 | error if system 'make'; 27 | } 28 | 29 | for my $slicing ('bitslice') { 30 | my $temp_dir = "tmp_subterranean_$slicing"; 31 | 32 | say "############################# Subterranean $slicing ############################"; 33 | 34 | # switching to usuba dir 35 | chdir "$FindBin::Bin/../.."; 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Subterranean from Usuba to C..."; 44 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B'; 45 | error if system "./usubac $slicing_flag -light-inline -bits-per-reg 8 -o $temp_dir/subterranean_ua_$slicing.c -arch std -no-sched $samples/usuba/subterranean.ua"; 46 | 47 | chdir $temp_dir; 48 | copy $_, "." for glob "$FindBin::Bin/subterranean/*"; 49 | 50 | # Compiling the C files 51 | say "Compiling the test executable..."; 52 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 53 | error if system "clang -D $implem_flag -march=native -I../arch -I . -o main main.c"; 54 | 55 | say "Running the test..."; 56 | error if system './main'; 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "$slicing Subterranean OK.\n\n"; 62 | } 63 | -------------------------------------------------------------------------------- /checks/correctness/check_xoodoo.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | use Cwd; 8 | use File::Path qw( remove_tree ); 9 | use File::Copy; 10 | use File::Copy::Recursive qw(rcopy dircopy); 11 | $File::Copy::Recursive::CPRFComp = 1; 12 | use FindBin; 13 | 14 | use require::relative "../../subroutines.pl"; 15 | 16 | my $samples = samples_location(); 17 | 18 | sub error { 19 | say "************ ERROR **************\n\n"; 20 | exit 1; 21 | } 22 | 23 | # Compiling the compiler. 24 | unless ($ARGV[0]) { 25 | say "Compiling..."; 26 | error if system 'make'; 27 | } 28 | 29 | for my $slicing ('vslice', 'bitslice') { 30 | my $temp_dir = "tmp_xoodoo_$slicing"; 31 | 32 | say "############################# Xoodoo $slicing ############################"; 33 | 34 | # switching to usuba dir 35 | chdir "$FindBin::Bin/../.."; 36 | 37 | # Switching to temporary directory. 38 | say "Preparing the files for the test..."; 39 | remove_tree $temp_dir if -d $temp_dir; 40 | mkdir $temp_dir; 41 | 42 | # Compiling Usuba Clyde. 43 | say "Compiling Xoodoo from Usuba to C..."; 44 | my $slicing_flag = $slicing eq 'vslice' ? '-V' : '-B -bits-per-reg 32'; 45 | error if system "./usubac $slicing_flag -o $temp_dir/xoodoo_ua_$slicing.c -arch std -no-sched $samples/usuba/xoodoo.ua"; 46 | 47 | chdir $temp_dir; 48 | copy $_, "." for glob "$FindBin::Bin/xoodoo/*"; 49 | 50 | # Compiling the C files 51 | say "Compiling the test executable..."; 52 | my $implem_flag = $slicing eq 'vslice' ? 'UA_V' : 'UA_B'; 53 | error if system "clang -D $implem_flag -march=native -I../arch -I . -o main main.c"; 54 | 55 | say "Running the test..."; 56 | error if system './main'; 57 | 58 | chdir '..'; 59 | remove_tree $temp_dir; 60 | 61 | say "$slicing Xoodoo OK.\n\n"; 62 | } 63 | -------------------------------------------------------------------------------- /checks/correctness/des/main.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define ORTHO 9 | #define RUNTIME 10 | 11 | #ifdef STD 12 | #include "STD.h" 13 | #else 14 | #ifdef SSE 15 | #include "SSE.h" 16 | #else 17 | #ifdef AVX 18 | #include "AVX.h" 19 | #else 20 | #error "No implementation provided" 21 | #endif 22 | #endif 23 | #endif 24 | 25 | 26 | #include "des.c" 27 | 28 | 29 | /* runtime */ 30 | 31 | #define BLOCK_SIZE 64 32 | #define KEY_SIZE 64 33 | 34 | int main() { 35 | 36 | // Hardcoding a key for now... 37 | uint64_t key_std = 0x133457799BBCDFF1; 38 | DATATYPE *key_ortho = ALLOC(KEY_SIZE); 39 | DATATYPE *key_cst = ALLOC(KEY_SIZE); 40 | 41 | for (int i = 0; i < 64; i++) 42 | if (key_std >> i & 1) 43 | key_ortho[63-i] = key_cst[63-i] = SET_ALL_ONE(); 44 | else 45 | key_ortho[63-i] = key_cst[63-i] = SET_ALL_ZERO(); 46 | 47 | 48 | // Reading the input file 49 | FILE* fh_in = fopen("input.txt","rb"); 50 | FILE* fh_out = fopen("output_to_test.txt","wb"); 51 | 52 | // Allocating various stuffs 53 | DATATYPE *plain_ortho = ALLOC(REG_SIZE); 54 | DATATYPE *cipher_ortho = ALLOC(REG_SIZE); 55 | uint64_t *plain_std = ALLOC(CHUNK_SIZE); 56 | 57 | 58 | while(fread(plain_std, 8, CHUNK_SIZE, fh_in)) { 59 | 60 | for (int i = 0; i < CHUNK_SIZE; i++) 61 | plain_std[i] = __builtin_bswap64(plain_std[i]); 62 | 63 | ORTHOGONALIZE(plain_std, plain_ortho); 64 | 65 | for (int i = 0; i < CHUNK_SIZE / REG_SIZE; i++) { 66 | 67 | memcpy(key_ortho,key_cst,KEY_SIZE*sizeof *key_cst); 68 | des__(&plain_ortho[i*64], key_ortho, &cipher_ortho[i*64]); 69 | 70 | } 71 | 72 | UNORTHOGONALIZE(cipher_ortho,plain_std); 73 | 74 | for (int i = 0; i < CHUNK_SIZE; i++) 75 | plain_std[i] = __builtin_bswap64(plain_std[i]); 76 | 77 | fwrite(plain_std, 8, CHUNK_SIZE, fh_out); 78 | } 79 | 80 | fclose(fh_in); 81 | fclose(fh_out); 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /checks/correctness/gift/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef REF 7 | 8 | #include "gift128.c" 9 | #define gift giftb128 10 | 11 | #elif defined(UA_V) 12 | 13 | #include "gift_ua_vslice.c" 14 | void gift(uint32_t text[4], uint16_t key16[8]) { 15 | uint32_t key[8]; 16 | for (int i = 0; i < 8; i++) 17 | key[i] = key16[i]; 18 | 19 | uint32_t output[4]; 20 | gift__(text,key,output); 21 | 22 | memcpy(text,output,16); 23 | } 24 | 25 | #elif defined(UA_B) 26 | 27 | #include "gift_ua_bitslice.c" 28 | /* Transposition stuffs */ 29 | static uint64_t mask_l[6] = { 30 | 0xaaaaaaaaaaaaaaaaUL, 31 | 0xccccccccccccccccUL, 32 | 0xf0f0f0f0f0f0f0f0UL, 33 | 0xff00ff00ff00ff00UL, 34 | 0xffff0000ffff0000UL, 35 | 0xffffffff00000000UL 36 | }; 37 | static uint64_t mask_r[6] = { 38 | 0x5555555555555555UL, 39 | 0x3333333333333333UL, 40 | 0x0f0f0f0f0f0f0f0fUL, 41 | 0x00ff00ff00ff00ffUL, 42 | 0x0000ffff0000ffffUL, 43 | 0x00000000ffffffffUL 44 | }; 45 | void transpose(uint64_t data[]) { 46 | for (int i = 0; i < 6; i ++) { 47 | int n = (1UL << i); 48 | for (int j = 0; j < 64; j += (2 * n)) 49 | for (int k = 0; k < n; k ++) { 50 | uint64_t u = data[j + k] & mask_l[i]; 51 | uint64_t v = data[j + k] & mask_r[i]; 52 | uint64_t x = data[j + n + k] & mask_l[i]; 53 | uint64_t y = data[j + n + k] & mask_r[i]; 54 | data[j + k] = u | (x >> n); 55 | data[j + n + k] = (v << n) | y; 56 | } 57 | } 58 | } 59 | 60 | void gift(uint32_t text[4], uint16_t key16[8]) { 61 | uint64_t text_bs[128]; 62 | for (int i = 0; i < 2; i++) { 63 | for (int j = 0; j < 64; j++) { 64 | text_bs[i*64+j] = ((uint64_t*)text)[i]; 65 | text_bs[i*64+j] = (text_bs[i*64+j] >> 32) | (text_bs[i*64+j] << 32); 66 | } 67 | transpose(&text_bs[i*64]); 68 | } 69 | 70 | uint64_t key_bs[8][32]; 71 | for (int i = 0; i < 8; i++) { 72 | for (int j = 0; j < 16; j++) 73 | key_bs[i][j] = 0; 74 | for (int j = 0; j < 16; j++) 75 | key_bs[i][j+16] = (key16[i] >> (15-j)) & 1 ? -1 : 0; 76 | } 77 | 78 | uint64_t output_bs[128]; 79 | gift__(text_bs, key_bs, output_bs); 80 | 81 | for (int i = 0; i < 2; i++) 82 | transpose(&output_bs[i*64]); 83 | 84 | memcpy(&text[0],&output_bs[0],8); 85 | memcpy(&text[2],&output_bs[64],8); 86 | #define SWAP(a,b) { a ^= b; b ^= a; a ^= b; } 87 | SWAP(text[0],text[1]); 88 | SWAP(text[2],text[3]); 89 | } 90 | 91 | 92 | #else 93 | #error Please define REF or UA_V 94 | #endif 95 | 96 | 97 | 98 | 99 | void test_gift() { 100 | 101 | // Uncomments the comments for a full of 0 plain/key. 102 | //uint32_t text[4] = { 0 }; 103 | uint32_t text[4] = { 0xaaa8353c, 0xd131b478, 0x95fde102, 0x2de5d87a }; 104 | //uint16_t key[8] = { 0 }; 105 | uint16_t key[8] = { 0x0123, 0x4567, 0x89ab, 0xcdef, 0xf0e1, 0xd2c3, 0xb4a5, 0x9687 }; 106 | 107 | gift(text, key); 108 | for (int i = 0; i < 4; i++) 109 | text[i] = __builtin_bswap32(text[i]); 110 | 111 | //uint32_t expected[4] = { 0x2e3a8e5e, 0x7da79716, 0xdc890bcc, 0xee647ad9 }; 112 | uint32_t expected[4] = { 0x739cfe1e, 0xb755869f, 0x603b349c, 0x889d5bad }; 113 | 114 | if (memcmp(text, expected, 16) != 0) { 115 | fprintf(stderr, "Error encryption.\n"); 116 | fprintf(stderr, "Expected : "); 117 | for (int i = 0; i < 4; i++) 118 | fprintf(stderr, "%08x ",expected[i]); 119 | fprintf(stderr, "\nGot : "); 120 | for (int i = 0; i < 4; i++) 121 | fprintf(stderr, "%08x ",text[i]); 122 | fprintf(stderr, "\n"); 123 | exit(EXIT_FAILURE); 124 | } else { 125 | fprintf(stderr, "Seems OK.\n"); 126 | } 127 | } 128 | 129 | int main() { 130 | test_gift(); 131 | } 132 | -------------------------------------------------------------------------------- /checks/correctness/gimli/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define STATE_SIZE (4*3*4) 7 | 8 | #include "gimli.c" 9 | 10 | #if defined(UA_V) 11 | void gimli(uint8_t* state) { 12 | gimli__((uint32_t*)state, (uint32_t*)state); 13 | } 14 | #elif defined(UA_B) 15 | void gimli(uint8_t* state) { 16 | uint64_t state_bs[STATE_SIZE*8]; 17 | for (int i = 0; i < 4*3; i++) 18 | ((uint32_t*)state)[i] = __builtin_bswap32(((uint32_t*)state)[i]); 19 | for (int i = 0; i < STATE_SIZE; i++) 20 | for (int j = 0; j < 8; j++) 21 | state_bs[i*8+j] = ((state[i] >> (7-j)) & 1) ? -1 : 0; 22 | gimli__(state_bs,state_bs); 23 | for (int i = 0; i < STATE_SIZE; i++) { 24 | uint8_t tmp = 0; 25 | for (int j = 0; j < 8; j++) 26 | tmp |= (state_bs[i*8+7-j]&1) << j; 27 | state[i] = tmp; 28 | } 29 | for (int i = 0; i < 4*3; i++) 30 | ((uint32_t*)state)[i] = __builtin_bswap32(((uint32_t*)state)[i]); 31 | } 32 | #else 33 | #error Please define UA_V or UA_B 34 | #endif 35 | 36 | 37 | void test_gimli() { 38 | 39 | // This seemingly random state is the result of encrypting a full 0 state 40 | uint8_t state[STATE_SIZE] = 41 | { 0xc4, 0xd8, 0x67, 0x64, 0x3b, 0xf8, 0xdc, 0x07, 0xd4, 0xb0, 0x0b, 0x3b, 42 | 0x4c, 0x36, 0x21, 0x1b, 0xdc, 0x31, 0x34, 0x08, 0x8e, 0xbe, 0xfb, 0x0e, 43 | 0x84, 0xe8, 0x54, 0x00, 0x55, 0xd9, 0x8b, 0x64, 0x2e, 0xb4, 0x5d, 0x4a, 44 | 0xcb, 0x41, 0x06, 0xca, 0xc2, 0xd2, 0x73, 0x86, 0x09, 0xd8, 0x30, 0x2e }; 45 | 46 | gimli(state); 47 | 48 | uint8_t expected[STATE_SIZE] = 49 | { 0x57, 0xa6, 0x9d, 0xf9, 0x78, 0x78, 0x6a, 0xfd, 0xe9, 0xea, 0x94, 0x88, 50 | 0x85, 0xfd, 0x59, 0xfd, 0x12, 0xcd, 0x41, 0x9f, 0x91, 0x18, 0x6a, 0x26, 51 | 0x31, 0xd8, 0x7a, 0xcf, 0xe9, 0xb6, 0x16, 0xf9, 0xe8, 0xa5, 0xa3, 0xb9, 52 | 0x51, 0xee, 0x7d, 0x3d, 0xfd, 0xe0, 0x0c, 0xf5, 0x5e, 0x00, 0x02, 0xf1 }; 53 | 54 | if (memcmp(state, expected, STATE_SIZE) != 0) { 55 | fprintf(stderr, "Encryption error.\n"); 56 | fprintf(stderr, "Expected: "); 57 | for (int i = 0; i < STATE_SIZE; i++) 58 | printf("%02x ", expected[i]); 59 | printf("\nGot : "); 60 | for (int i = 0; i < STATE_SIZE; i++) 61 | printf("%02x ", state[i]); 62 | printf("\n"); 63 | exit(EXIT_FAILURE); 64 | } 65 | } 66 | 67 | 68 | int main() { 69 | test_gimli(); 70 | } 71 | -------------------------------------------------------------------------------- /checks/correctness/photon/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef REF 7 | 8 | #include "photon.c" 9 | #define photon(text) Permutation(text,12) 10 | 11 | #elif defined(UA_V) 12 | 13 | #include "photon_ua_vslice.c" 14 | void photon(unsigned char text[8][8]) { 15 | 16 | unsigned char output[8][8]; 17 | Photon__(text,output); 18 | 19 | for (int i = 0; i < 8; i++) 20 | for (int j = 0; j < 8; j++) 21 | text[i][j] = output[i][j]; 22 | } 23 | 24 | #elif defined(UA_B) 25 | 26 | #include "photon_ua_bitslice.c" 27 | void photon(unsigned char text[8][8]) { 28 | uint64_t input[8][8][4]; 29 | for (int i = 0; i < 8; i++) 30 | for (int j = 0; j < 8; j++) 31 | for (int k = 0; k < 4; k++) 32 | input[i][j][3-k] = (text[i][j] >> k) & 1 ? -1 : 0; 33 | 34 | uint64_t output[8][8][4]; 35 | Photon__(input,output); 36 | 37 | for (int i = 0; i < 8; i++) 38 | for (int j = 0; j < 8; j++) { 39 | unsigned char tmp = 0; 40 | for (int k = 0; k < 4; k++) 41 | tmp |= (output[i][j][k] & 1) << (3-k); 42 | text[i][j] = tmp; 43 | } 44 | } 45 | 46 | #else 47 | #error Please define REF or UA_V 48 | #endif 49 | 50 | 51 | 52 | 53 | void test_photon() { 54 | 55 | // This seemigly random input is produced by encrypting full 0s plain 56 | unsigned char text[8][8] = { 57 | { 0x0, 0x1, 0x1, 0x6, 0x5, 0x9, 0x0, 0x7 }, 58 | { 0xd, 0xb, 0xd, 0xa, 0x6, 0x5, 0x9, 0xc }, 59 | { 0x2, 0xa, 0xf, 0x1, 0x7, 0x0, 0x4, 0xb }, 60 | { 0xb, 0xa, 0x9, 0x3, 0xe, 0x7, 0x4, 0xb }, 61 | { 0xa, 0x0, 0x5, 0xc, 0x1, 0xa, 0xb, 0x3 }, 62 | { 0x8, 0xb, 0x8, 0xd, 0x4, 0x5, 0x8, 0x2 }, 63 | { 0x6, 0x0, 0xd, 0xf, 0xf, 0x0, 0x4, 0xc }, 64 | { 0x0, 0x6, 0x2, 0xd, 0x7, 0x2, 0xe, 0x5 } }; 65 | 66 | photon(text); 67 | 68 | /* for (int i = 0; i < 8; i++) { */ 69 | /* for (int j = 0; j < 8; j++) { */ 70 | /* printf("0x%01x, ",text[i][j]&0xf); */ 71 | /* } */ 72 | /* printf("\n"); */ 73 | /* } */ 74 | 75 | unsigned char expected[8][8] = { 76 | { 0xb, 0xf, 0x1, 0xc, 0x0, 0x6, 0x6, 0x8 }, 77 | { 0x1, 0x2, 0x2, 0x9, 0x9, 0xb, 0x6, 0xf }, 78 | { 0x3, 0x9, 0xf, 0x6, 0xf, 0xc, 0x8, 0xa }, 79 | { 0xa, 0x7, 0x2, 0xf, 0x7, 0xf, 0xc, 0x1 }, 80 | { 0xf, 0x4, 0xf, 0xc, 0xa, 0x3, 0xe, 0x3 }, 81 | { 0x7, 0xa, 0x0, 0x5, 0x6, 0xc, 0x6, 0x5 }, 82 | { 0xc, 0x1, 0xd, 0x2, 0xa, 0x6, 0x3, 0xb }, 83 | { 0xb, 0x4, 0x8, 0xf, 0x2, 0x5, 0x5, 0xd } }; 84 | 85 | if (memcmp(text, expected, 64) != 0) { 86 | fprintf(stderr, "Error encryption.\n"); 87 | fprintf(stderr, "Expected : "); 88 | for (int i = 0; i < 8; i++) { 89 | for (int j = 0; j < 8; j++) fprintf(stderr, "%01x",expected[i][j]&0xf); 90 | fprintf(stderr," "); 91 | } 92 | fprintf(stderr, "\nGot : "); 93 | for (int i = 0; i < 8; i++) { 94 | for (int j = 0; j < 8; j++) fprintf(stderr, "%01x",text[i][j]&0xf); 95 | fprintf(stderr," "); 96 | } 97 | fprintf(stderr, "\n"); 98 | exit(EXIT_FAILURE); 99 | } else { 100 | fprintf(stderr, "Seems OK.\n"); 101 | } 102 | } 103 | 104 | 105 | int main() { 106 | test_photon(); 107 | } 108 | -------------------------------------------------------------------------------- /checks/correctness/pyjamask/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_KEYBYTES 16 2 | #define CRYPTO_NSECBYTES 0 3 | #define CRYPTO_NPUBBYTES 12 4 | #define CRYPTO_ABYTES 16 5 | #define CRYPTO_NOOVERLAP 1 6 | -------------------------------------------------------------------------------- /checks/correctness/pyjamask/pyjamask.h: -------------------------------------------------------------------------------- 1 | /* 2 | =============================================================================== 3 | 4 | Header file for Pyjamsk block ciphers in C 5 | 6 | Copyright (C) 2019 Dahmun Goudarzi, Jérémy Jean, Stefan Kölbl, 7 | Thomas Peyrin, Matthieu Rivain, Yu Sasaki, Siang Meng Sim 8 | 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | =============================================================================== 23 | */ 24 | 25 | void pyjamask_96_enc (const unsigned char *plaintext, const unsigned char *key, unsigned char *ciphertext); 26 | void pyjamask_96_dec (const unsigned char *ciphertext, const unsigned char *key, unsigned char *plaintext); 27 | 28 | void pyjamask_128_enc(const unsigned char *plaintext, const unsigned char *key, unsigned char *ciphertext); 29 | void pyjamask_128_dec(const unsigned char *ciphertext, const unsigned char *key, unsigned char *plaintext ); 30 | void key_schedule(const uint8_t *key, uint32_t* round_keys); 31 | -------------------------------------------------------------------------------- /checks/correctness/pyjamask_masked/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_KEYBYTES 16 2 | #define CRYPTO_NSECBYTES 0 3 | #define CRYPTO_NPUBBYTES 12 4 | #define CRYPTO_ABYTES 16 5 | #define CRYPTO_NOOVERLAP 1 6 | -------------------------------------------------------------------------------- /checks/correctness/pyjamask_masked/pyjamask.h: -------------------------------------------------------------------------------- 1 | /* 2 | =============================================================================== 3 | 4 | Header file for Pyjamsk block ciphers in C 5 | 6 | Copyright (C) 2019 Dahmun Goudarzi, Jérémy Jean, Stefan Kölbl, 7 | Thomas Peyrin, Matthieu Rivain, Yu Sasaki, Siang Meng Sim 8 | 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | =============================================================================== 23 | */ 24 | 25 | void pyjamask_96_enc (const unsigned char *plaintext, const unsigned char *key, unsigned char *ciphertext); 26 | void pyjamask_96_dec (const unsigned char *ciphertext, const unsigned char *key, unsigned char *plaintext); 27 | 28 | void pyjamask_128_enc(const unsigned char *plaintext, const unsigned char *key, unsigned char *ciphertext); 29 | void pyjamask_128_dec(const unsigned char *ciphertext, const unsigned char *key, unsigned char *plaintext ); 30 | void key_schedule(const uint8_t *key, uint32_t* round_keys); 31 | -------------------------------------------------------------------------------- /checks/correctness/serpent/serpent.h: -------------------------------------------------------------------------------- 1 | /* aes.h */ 2 | 3 | /* AES Cipher header file for ANSI C Submissions 4 | Lawrence E. Bassham III 5 | Computer Security Division 6 | National Institute of Standards and Technology 7 | 8 | April 15, 1998 9 | 10 | This sample is to assist implementers developing to the Cryptographic 11 | API Profile for AES Candidate Algorithm Submissions. Please consult this 12 | document as a cross-reference. 13 | 14 | ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE 15 | MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH 16 | THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS CANNOT 17 | BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO INCLUDE 18 | IMPLEMENTATION SPECIFIC INFORMATION. 19 | */ 20 | 21 | /* Includes: 22 | Standard include files 23 | */ 24 | 25 | #include 26 | 27 | /* Defines: 28 | Add any additional defines you need 29 | */ 30 | 31 | #define DIR_ENCRYPT 0 /* Are we encrpyting? */ 32 | #define DIR_DECRYPT 1 /* Are we decrpyting? */ 33 | #define MODE_ECB 1 /* Are we ciphering in ECB mode? */ 34 | #define MODE_CBC 2 /* Are we ciphering in CBC mode? */ 35 | #define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ 36 | #define TRUE 1 37 | #define FALSE 0 38 | 39 | /* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */ 40 | #define BAD_KEY_DIR -1 /* Key direction is invalid, e;g;, 41 | unknown value */ 42 | #define BAD_KEY_MAT -2 /* Key material not of correct 43 | length */ 44 | #define BAD_KEY_INSTANCE -3 /* Key passed is not valid */ 45 | #define BAD_CIPHER_MODE -4 /* Params struct passed to 46 | cipherInit invalid */ 47 | #define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not 48 | initialized) */ 49 | 50 | /* CHANGE POSSIBLE: inclusion of algorithm specific defines */ 51 | #define MAX_KEY_SIZE 64 /* # of ASCII char's needed to 52 | represent a key */ 53 | #define MAX_IV_SIZE 32 /* # of ASCII char's needed to 54 | represent an IV */ 55 | 56 | /* Typedefs: 57 | 58 | Typedef'ed data storage elements. Add any algorithm specific 59 | parameters at the bottom of the structs as appropriate. 60 | */ 61 | 62 | typedef unsigned char BYTE; 63 | 64 | /* The structure for key information */ 65 | typedef struct { 66 | BYTE direction; /* Key used for encrypting or decrypting? */ 67 | int keyLen; /* Length of the key */ 68 | char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., 69 | what the user types or KAT values)*/ 70 | /* The following parameters are algorithm dependent, replace or 71 | add as necessary */ 72 | unsigned int key[8]; /* The key in binary */ 73 | unsigned int subkeys[33][4]; /* Serpent subkeys */ 74 | } keyInstance; 75 | 76 | /* The structure for cipher information */ 77 | typedef struct { 78 | BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ 79 | char IV[MAX_IV_SIZE]; /* A possible Initialization Vector for 80 | ciphering */ 81 | /* Add any algorithm specific parameters needed here */ 82 | int blockSize; /* Sample: Handles non-128 bit block sizes 83 | (if available) */ 84 | } cipherInstance; 85 | 86 | 87 | /* Function protoypes */ 88 | int makeKey(keyInstance *key, BYTE direction, int keyLen, 89 | char *keyMaterial); 90 | 91 | int cipherInit(cipherInstance *cipher, BYTE mode, char *IV); 92 | 93 | int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, 94 | int inputLen, BYTE *outBuffer); 95 | 96 | int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, 97 | int inputLen, BYTE *outBuffer); 98 | -------------------------------------------------------------------------------- /checks/correctness/spongent/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef REF 7 | 8 | #include "spongent.c" 9 | #define spongent permutation 10 | 11 | #elif defined(UA_B) 12 | 13 | #include "spongent_ua_bitslice.c" 14 | /* Transposition stuffs */ 15 | static uint32_t mask_l[5] = { 16 | 0xaaaaaaaa, 17 | 0xcccccccc, 18 | 0xf0f0f0f0, 19 | 0xff00ff00, 20 | 0xffff0000 21 | }; 22 | static uint32_t mask_r[5] = { 23 | 0x55555555, 24 | 0x33333333, 25 | 0x0f0f0f0f, 26 | 0x00ff00ff, 27 | 0x0000ffff 28 | }; 29 | void transpose(uint32_t data[]) { 30 | for (int i = 0; i < 5; i ++) { 31 | int n = (1UL << i); 32 | for (int j = 0; j < 32; j += (2 * n)) 33 | for (int k = 0; k < n; k ++) { 34 | uint64_t u = data[j + k] & mask_l[i]; 35 | uint64_t v = data[j + k] & mask_r[i]; 36 | uint64_t x = data[j + n + k] & mask_l[i]; 37 | uint64_t y = data[j + n + k] & mask_r[i]; 38 | data[j + k] = u | (x >> n); 39 | data[j + n + k] = (v << n) | y; 40 | } 41 | } 42 | } 43 | 44 | void spongent(unsigned char text[20]) { 45 | uint32_t text_bs[20][8]; 46 | for (int i = 0; i < 20; i++) 47 | for (int j = 0; j < 8; j++) 48 | text_bs[i][j] = (text[i] >> (7-j)) & 1 ? -1 : 0; 49 | 50 | uint32_t output_bs[20][8]; 51 | permutation__(text_bs,output_bs); 52 | 53 | for (int i = 0; i < 20; i++) { 54 | unsigned char c = 0; 55 | for (int j = 0; j < 8; j++) 56 | c |= output_bs[i][j] ? (1 << (7-j)) : 0; 57 | text[i] = c; 58 | } 59 | } 60 | 61 | 62 | #else 63 | #error Please define REF or UA_V 64 | #endif 65 | 66 | 67 | 68 | 69 | void test_spongent() { 70 | 71 | // This seemigly random input is produced by encrypting full 0s plain 72 | /* unsigned char text[20] = { 0 }; */ 73 | unsigned char text[20] = { 74 | 0xe8, 0x0c, 0x00, 0x86, 0xa2, 0xcb, 0x82, 0x86, 0xa1, 0x62, 75 | 0xc5, 0x0e, 0xde, 0x3e, 0xd1, 0xb9, 0x5f, 0x74, 0xed, 0xca 76 | }; 77 | 78 | spongent(text); 79 | 80 | /* unsigned char expected[20] = { */ 81 | /* 0xe8, 0x0c, 0x00, 0x86, 0xa2, 0xcb, 0x82, 0x86, 0xa1, 0x62, */ 82 | /* 0xc5, 0x0e, 0xde, 0x3e, 0xd1, 0xb9, 0x5f, 0x74, 0xed, 0xca */ 83 | /* }; */ 84 | unsigned char expected[20] = { 85 | 0x0d, 0x7f, 0x1a, 0xf2, 0xc8, 0x5e, 0xb8, 0x0f, 0x1b, 0x95, 86 | 0xcc, 0x80, 0x60, 0x5f, 0x10, 0x56, 0x8e, 0x6e, 0x34, 0xac 87 | }; 88 | 89 | if (memcmp(text, expected, 20) != 0) { 90 | fprintf(stderr, "Error encryption.\n"); 91 | fprintf(stderr, "Expected : "); 92 | for (int i = 0; i < 20; i++) 93 | fprintf(stderr, "%02x ",expected[i]); 94 | fprintf(stderr, "\nGot : "); 95 | for (int i = 0; i < 20; i++) 96 | fprintf(stderr, "%02x ",text[i]); 97 | fprintf(stderr,"\n"); 98 | exit(EXIT_FAILURE); 99 | } else { 100 | fprintf(stderr, "Seems OK.\n"); 101 | } 102 | } 103 | 104 | 105 | int main() { 106 | test_spongent(); 107 | } 108 | -------------------------------------------------------------------------------- /checks/correctness/subterranean/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef REF 7 | 8 | #include "subterranean_ref.c" 9 | 10 | void subterranean(uint8_t x[257]) { 11 | subterranean_blank(x,8); 12 | } 13 | 14 | 15 | #elif defined(UA_B) 16 | 17 | #include "subterranean_ua_bitslice.c" 18 | 19 | void subterranean(uint8_t x[257]) { 20 | blank__(x,x); 21 | } 22 | 23 | #else 24 | #error Please define REF or UA_VDRYSPONGE_MixPhase 25 | #endif 26 | 27 | 28 | void test_subterranean() { 29 | 30 | // This seemigly random input is produced by encrypting full 0s plain 31 | //uint8_t text[257] = { 0 }; 32 | uint8_t text[257] = { 0,0,0,1,0,0,1,1,1,1,0,1,0,0,0,0,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,1,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,1,1,0,1,1,1,0,1,0,0,0,0,1,0,1,1,1,1,0,0,1,0,1,0,1,0,1,0,0,0,1,1,0,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,1,1,0,0,1,0,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,1,1,1,1,0,1,1,0,1,0,1,0,0,1,0,0,0,1,1,1,1,1,0,1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,1 }; 33 | 34 | subterranean(text); 35 | /* cleaning the output because Usuba uses ~x instead of x^1, thus 36 | polluting some other bits */ 37 | for (int i = 0; i < 257; i++) text[i] &= 1; 38 | 39 | /* uint8_t expected[257] = { 0,0,0,1,0,0,1,1,1,1,0,1,0,0,0,0,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,1,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,1,1,0,1,1,1,0,1,0,0,0,0,1,0,1,1,1,1,0,0,1,0,1,0,1,0,1,0,0,0,1,1,0,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,1,1,0,0,1,0,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,1,1,1,1,0,1,1,0,1,0,1,0,0,1,0,0,0,1,1,1,1,1,0,1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,1 }; */ 40 | uint8_t expected[257] = { 0,0,0,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,0,1,0,1,1,0,0,1,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,0,0,1,0,0,0,1,1,0,1,1,1,0,0,1,0,1,1,0,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,1,0,0,0,0,1,1,0,1,0,1,1,0,0,1,1,0,0,0,0,0,0,0,1,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0,1,0,1,0,1,1,1,1,1,0,0,0,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,0,0,1,0,1,1,1,1,0,0,0,0,1,1,0,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,1,1,0,0,0,1,1,0,0,0,0,0 }; 41 | 42 | if (memcmp(text, expected, 257) != 0) { 43 | fprintf(stderr, "Error encryption.\n"); 44 | fprintf(stderr, "Expected : "); 45 | for (int i = 0; i < 257; i++) fprintf(stderr, "%d", expected[i]&1); 46 | fprintf(stderr, "\nGot : "); 47 | for (int i = 0; i < 257; i++) fprintf(stderr, "%d", text[i]&1); 48 | fprintf(stderr, "\n"); 49 | exit(EXIT_FAILURE); 50 | } else { 51 | fprintf(stderr, "Seems OK.\n"); 52 | } 53 | } 54 | 55 | 56 | int main() { 57 | test_subterranean(); 58 | } 59 | -------------------------------------------------------------------------------- /checks/correctness/xoodoo/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef REF 7 | 8 | #error Not defined with REF 9 | 10 | #elif defined(UA_V) 11 | #include "xoodoo_ua_vslice.c" 12 | 13 | void xoodoo(uint32_t state[3*4]) { 14 | uint32_t input[3][4]; 15 | memcpy(input,state,3*4*4); 16 | uint32_t output[3][4]; 17 | xoodoo__(input,output); 18 | memcpy(state,output,3*4*4); 19 | } 20 | 21 | #elif defined(UA_B) 22 | #include "xoodoo_ua_bitslice.c" 23 | /* Transposition stuffs */ 24 | static uint32_t mask_l[5] = { 25 | 0xaaaaaaaa, 26 | 0xcccccccc, 27 | 0xf0f0f0f0, 28 | 0xff00ff00, 29 | 0xffff0000 30 | }; 31 | static uint32_t mask_r[5] = { 32 | 0x55555555, 33 | 0x33333333, 34 | 0x0f0f0f0f, 35 | 0x00ff00ff, 36 | 0x0000ffff 37 | }; 38 | void transpose(uint32_t data[]) { 39 | for (int i = 0; i < 5; i ++) { 40 | int n = (1UL << i); 41 | for (int j = 0; j < 32; j += (2 * n)) 42 | for (int k = 0; k < n; k ++) { 43 | uint64_t u = data[j + k] & mask_l[i]; 44 | uint64_t v = data[j + k] & mask_r[i]; 45 | uint64_t x = data[j + n + k] & mask_l[i]; 46 | uint64_t y = data[j + n + k] & mask_r[i]; 47 | data[j + k] = u | (x >> n); 48 | data[j + n + k] = (v << n) | y; 49 | } 50 | } 51 | } 52 | 53 | void xoodoo(uint32_t _state[3*4]) { 54 | uint32_t state[3][4]; 55 | memcpy(state,_state,3*4*4); 56 | 57 | uint32_t input_bs[3][4][32]; 58 | for (int i = 0; i < 3; i++) 59 | for (int j = 0; j < 4; j++) { 60 | for (int k = 0; k < 32; k++) 61 | input_bs[i][j][k] = state[i][j]; 62 | transpose(input_bs[i][j]); 63 | } 64 | 65 | uint32_t output_bs[3][4][32]; 66 | xoodoo__(input_bs,output_bs); 67 | 68 | for (int i = 0; i < 3; i++) 69 | for (int j = 0; j < 4; j++) { 70 | transpose(output_bs[i][j]); 71 | state[i][j] = output_bs[i][j][0]; 72 | } 73 | memcpy(_state,state,3*4*4); 74 | } 75 | 76 | 77 | 78 | #else 79 | #error Please define REF or UA_V 80 | #endif 81 | 82 | 83 | 84 | 85 | void test_xoodoo() { 86 | 87 | // This seemigly random input is produced by encrypting full 0s plain 88 | /* uint32_t state[3*4] = { 0 }; */ 89 | uint32_t state[3*4] = { 90 | 0x89d5d88d, 0xa963fcbf, 0x1b232d19, 0xffa5a014, 91 | 0x36b18106, 0xafc7c1fe, 0xaee57cbe, 0xa77540bd, 92 | 0x2e86e870, 0xfef5b7c9, 0x8b4fadf2, 0x5e4f4062 }; 93 | 94 | xoodoo(state); 95 | 96 | /* uint32_t expected[3*4] = { */ 97 | /* 0x89d5d88d, 0xa963fcbf, 0x1b232d19, 0xffa5a014, */ 98 | /* 0x36b18106, 0xafc7c1fe, 0xaee57cbe, 0xa77540bd, */ 99 | /* 0x2e86e870, 0xfef5b7c9, 0x8b4fadf2, 0x5e4f4062 }; */ 100 | uint32_t expected[3*4] = { 101 | 0x7800275b, 0x7a3685b4, 0xaf055416, 0x8e6682e1, 102 | 0x6c704342, 0x2ca90ca3, 0xbd3d8ec0, 0xe1c94ea9, 103 | 0xa4399cad, 0x45b9d15b, 0x29b45758, 0x554aa496 }; 104 | 105 | if (memcmp(state, expected, 3*4*4) != 0) { 106 | fprintf(stderr, "Error encryption.\n"); 107 | fprintf(stderr, "Expected : "); 108 | for (int i = 0; i < 3*4; i++) fprintf(stderr, "%08x ",expected[i]); 109 | fprintf(stderr, "\nGot : "); 110 | for (int i = 0; i < 3*4; i++) fprintf(stderr, "%08x ",state[i]); 111 | fprintf(stderr, "\n"); 112 | exit(EXIT_FAILURE); 113 | } 114 | } 115 | 116 | 117 | int main() { 118 | test_xoodoo(); 119 | } 120 | -------------------------------------------------------------------------------- /cmp.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use List::Util qw(sum max); 6 | use feature 'say'; 7 | 8 | my $tot = 1; 9 | my $G = 1000000000; 10 | if ($ARGV[0] =~ /^\d+$/) { 11 | $tot = shift @ARGV; 12 | } 13 | 14 | my %times; 15 | 16 | for ( 1 .. $tot ) { 17 | for (@ARGV) { 18 | push @{$times{$_}}, (`./$_` =~ s/ .*$//r)+0; 19 | } 20 | } 21 | 22 | my %formatted; 23 | for (@ARGV) { 24 | my $u = sum(@{$times{$_}})/@{$times{$_}}; # mean 25 | my $s = ( sum( map {($_-$u)**2} @{$times{$_}} ) / @{$times{$_}} ) ** 0.5; # standard deviation 26 | $formatted{$_} = { mean => $u, stdev => $s }; 27 | } 28 | 29 | my $padding = max map { length } @ARGV; 30 | 31 | say "Details:"; 32 | for (sort { $formatted{$a}->{mean} <=> $formatted{$b}->{mean} } keys %formatted) { 33 | printf "%*s => %.3f +-%.3f [%s]\n", $padding, $_, $formatted{$_}->{mean}, $formatted{$_}->{stdev}, join ", ", @{$times{$_}}; 34 | } 35 | 36 | say "\nSummary:"; 37 | for (sort { $formatted{$a}->{mean} <=> $formatted{$b}->{mean} } keys %formatted) { 38 | printf "%*s => %.3f +-%.3f\n", $padding, $_, $formatted{$_}->{mean}, $formatted{$_}->{stdev} 39 | } 40 | -------------------------------------------------------------------------------- /config.json.help: -------------------------------------------------------------------------------- 1 | This file explains how `config.json` works. 2 | --- 3 | 4 | `config.json` must define 4 variables: 5 | 6 | - data_dir: the directory where to find all data needed by Usubac to 7 | compile. For now, those data are only the sboxes. You should 8 | probably leave it as is unless you know precisely what you are 9 | doing. 10 | 11 | - arch_dir: the directory where to find the C headers for each 12 | architecture. 13 | 14 | - tightprove_cache: the directory to use a cache for tightprove when 15 | compiling Usuba files with `-tp`. If you do not already have a 16 | cache from a previous installation of Usuba, you can probably 17 | leave it as is. 18 | 19 | - sage: the command to invoke to run SageMath. If you have a 20 | system-wide installation of SageMath, then setting it as "sage" 21 | should work. Otherwise, specify the full path of you sage 22 | installation. 23 | 24 | - tightprove: the full path of the tightPROVE+ binary. 25 | 26 | 27 | You can use the following placeholders: 28 | 29 | - {{USUBA}}: this is replaced by the full path of the current 30 | folder. 31 | 32 | - {{HOME}}: this is replaced by your home, as per the environment 33 | variable $HOME. Note that this probably will not work on Windows. -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ocamlc -c -o /tmp/ansi_terminal src/ansi_terminal.ml 3 | ocaml unix.cma -I /tmp/ /tmp/ansi_terminal.cmo configure.ml "$@" 4 | rm /tmp/ansi_terminal.cmi /tmp/ansi_terminal.cmo 5 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bullseye-slim 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | RUN apt-get update && \ 5 | apt-get install -qq --no-install-recommends \ 6 | sudo \ 7 | clang-11 \ 8 | gcc-10 \ 9 | opam \ 10 | cpanminus \ 11 | git \ 12 | ssh \ 13 | ca-certificates && \ 14 | update-alternatives --install /usr/bin/clang clang /usr/bin/clang-11 1000 && \ 15 | useradd -d /home/eval -m -s /bin/bash eval && \ 16 | echo "eval ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/eval && \ 17 | chmod 0440 /etc/sudoers.d/eval && \ 18 | passwd -l eval && \ 19 | chown -R eval:eval /home/eval 20 | 21 | USER eval 22 | ENV HOME /home/eval 23 | WORKDIR /home/eval 24 | 25 | # Setup opam 26 | RUN opam init --disable-sandboxing -a -y && \ 27 | opam install dune 28 | 29 | # Bring up Usuba 30 | RUN git clone --recurse-submodules https://github.com/usubalang/usuba.git && \ 31 | git clone --recurse-submodules https://github.com/usubalang/benchmarks.git && \ 32 | cd usuba && \ 33 | opam switch create . --yes --deps-only --with-doc --with-test && \ 34 | opam exec -- ./configure 35 | 36 | # Bring up Perl dependencies (for benchmarks) 37 | RUN sudo cpanm install -f File::Copy::Recursive \ 38 | JSON \ 39 | Statistics::Test::WilcoxonRankSum \ 40 | Parallel::ForkManager 41 | 42 | ENTRYPOINT [ "opam", "exec", "--"] 43 | CMD ["/bin/bash", "-c", "ulimit -s unlimited && cd benchmarks && perl bench_perfs.pl" ] 44 | -------------------------------------------------------------------------------- /docker/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean 2 | 3 | bench: 4 | docker run usuba 5 | 6 | run: 7 | docker run -ti usuba /bin/bash 8 | 9 | build: 10 | docker build \ 11 | --tag=usuba \ 12 | . 13 | 14 | clean: 15 | docker build \ 16 | --tag=usuba \ 17 | --no-cache \ 18 | . 19 | -------------------------------------------------------------------------------- /docs/grammar.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usubalang/usuba/4553c25c3d8abd8bcbb2edf75740a3c6d0ca1222/docs/grammar.pdf -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 3.3) 2 | 3 | (implicit_transitive_deps true) 4 | 5 | ; Menhir options 6 | (using menhir 2.0) 7 | 8 | ; Since we want to generate opam files we need to provide informations ; 9 | (generate_opam_files true) 10 | 11 | (name usuba) 12 | (version dev) 13 | (authors "Usuba developers") 14 | (maintainers "Usuba developers") 15 | (source (github usuba-lang/usuba)) 16 | ; Not specifying bug_reports since it defaults to the github issue page 17 | (homepage "https://usubalang.github.io/usuba/") 18 | (documentation "https://usubalang.github.io/usuba/") 19 | 20 | ; Packages 21 | 22 | (package 23 | (name usuba) 24 | (synopsis "Usuba") 25 | (description "\ 26 | TODO") 27 | (depends 28 | (ocaml (= 4.14.0)) 29 | (dune (= 3.3.1)) 30 | sexplib 31 | (usuba_lib (= :version)) 32 | (usuba_pp (= :version)) 33 | (odoc :with-doc) 34 | (ocamlformat (= 0.23.0)) 35 | ) 36 | ) 37 | 38 | (package 39 | (name usuba_lib) 40 | (synopsis "Usuba Library") 41 | (description "\ 42 | TODO") 43 | (depends 44 | (ocaml (= 4.14.0)) 45 | (dune (= 3.3.1)) 46 | menhir 47 | ppx_deriving 48 | sexplib 49 | ppx_sexp_conv 50 | (usuba_pp (= :version)) 51 | (odoc :with-doc) 52 | (ocamlformat (= 0.23.0)) 53 | (alcotest :with-test) 54 | (ppx_inline_test :with-test) 55 | ) 56 | ) 57 | 58 | (package 59 | (name usuba_pp) 60 | (synopsis "Usuba PP") 61 | (description "\ 62 | Pretty printing for stdlib modules") 63 | (depends 64 | (ocaml (= 4.14.0)) 65 | (dune (= 3.3.1)) 66 | (odoc :with-doc) 67 | (ocamlformat (= 0.23.0)) 68 | ) 69 | ) 70 | -------------------------------------------------------------------------------- /install_deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Installing OCaml 4 | if [ ! $(command -v ocaml) ]; then 5 | echo "OCaml not found. Installing it..."; 6 | sudo apt install -y ocaml 7 | fi 8 | 9 | # Installing and configuring Opam (OCaml package manager) 10 | if [ ! $(command -v opam) ]; then 11 | echo "Opam not found. Installing it..."; 12 | sudo apt install -y opam 13 | opam init -y 14 | eval `opam config env` 15 | fi 16 | 17 | # Installing required packages from opam 18 | opam install -y dune menhir 19 | 20 | # Installing required modules for Perl scripts 21 | sudo cpanm Crypt::Mode::ECB 22 | -------------------------------------------------------------------------------- /instr.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -nl 2 | 3 | $m+=()=/mov/g; 4 | $a+=()=/and(?!n)/g; 5 | $an+=()=/andn/g; 6 | $x+=()=/xor/g; 7 | $n+=()=/not/g; 8 | $o+=()=/(? 'D' | '-' -> 'H' | c -> c) s 13 | else s) 14 | end 15 | 16 | module List = struct 17 | let pp ?(pp_sep = fun ppf () -> Format.fprintf ppf "; ") ?(left = "[") 18 | ?(right = "]") pp ppf l = 19 | Format.fprintf ppf "%s%a%s" left Format.(pp_print_list ~pp_sep pp) l right 20 | 21 | let pp_tree = 22 | let pp_sep ppf () = Format.fprintf ppf "@,├───" in 23 | let pp_end ppf () = Format.fprintf ppf "@,└───" in 24 | fun pp ppf l -> 25 | let rec aux = function 26 | | [] -> () 27 | | [ v ] -> pp ppf v 28 | | [ v1; v2 ] -> 29 | pp ppf v1; 30 | pp_end ppf (); 31 | pp ppf v2 32 | | hd :: tl -> 33 | pp ppf hd; 34 | pp_sep ppf (); 35 | aux tl 36 | in 37 | match l with 38 | | [] -> () 39 | | _ -> 40 | Format.fprintf ppf "├───"; 41 | aux l 42 | end 43 | -------------------------------------------------------------------------------- /reduce.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use v5.14; 6 | 7 | 8 | our $DEBUG = 1; 9 | 10 | # Read whole file at once; who even cares about memory? 11 | my @data = <>; 12 | 13 | 14 | my @registers = qw(i7 i6 i5 i4 i3 i2 i1 i0 l7 l6 l5 l4 l3 l2 l1 l0 15 | o7 o6 o5 o4 o3 o2 o1 o0 g7 g6 g5 g4 g3 g2 g1 g0); 16 | my %reg_encoding = do { my $i = 0; map { $_ => $i++ } reverse @registers }; 17 | 18 | my %opcodes = ( ANDOR => [ 0b10, 0b101100] ); 19 | 20 | for (my $i = 0; $i < @data; $i++) { 21 | local $_ = $data[$i]; 22 | if (/.word 0xa5640011/) { # ANDOR 23 | my @bits = split //, sprintf "%b",hex "a5640011"; 24 | my ($op1, $op2) = map 25 | { /mov\s*\%(\S+),\s*\%(\S+)/ || die "$i: $_"; $1 } 26 | @data[$i-2, $i-1]; 27 | my ($dst) = $data[$i+1] =~ /mov\s*\%\S+,\s*\%(\S+)/ or die "$i: $_"; 28 | my ($op1_enc, $op2_enc, $dst_enc) = map { $reg_encoding{$_} // die "$i: $_" } 29 | ($op1, $op2, $dst); 30 | my ($op, $op3) = @{$opcodes{ANDOR}}; 31 | my $instr = emit($op, $op3, $dst_enc, $op1_enc, $op2_enc); 32 | splice @data, $i-2, 3, $instr; 33 | $i--; 34 | } 35 | } 36 | 37 | print for @data; 38 | 39 | 40 | 41 | sub emit { 42 | my ($op, $op3, $dst, $op1, $op2) = @_; 43 | my $bin_instr = sprintf "%02b%05b%06b%05b000000000%05b", $op, $dst, $op3, $op1, $op2; 44 | return sprintf "\t.word\t0x%08x\n", oct("0b$bin_instr"); 45 | } 46 | -------------------------------------------------------------------------------- /run_checks.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | =head1 Description 4 | 5 | This scripts checks that the code generated by Usuba for the 6 | ciphers DES (bitslice), AES (bitslice/hslice), Serpent (vslice) 7 | and Chacha20 (vslice) are correct. 8 | 9 | All the work is actually handed to the scripts of 10 | checks/correctness, but they all do similar things: they compile 11 | the Usuba source, link the resulting C file with a runtime, and 12 | compare the output they produce with a reference implementation 13 | (or a reference output in the case of Chacha20). 14 | 15 | =cut 16 | 17 | use strict; 18 | use warnings; 19 | use v5.14; 20 | 21 | use Cwd; 22 | use File::Path qw( remove_tree ); 23 | use File::Copy; 24 | use FindBin; 25 | 26 | require './subroutines.pl'; 27 | 28 | my $samples = samples_location(); 29 | 30 | sub error { 31 | say "************ ERROR **************\n\n"; 32 | exit 1; 33 | } 34 | 35 | # switching to usuba dir 36 | chdir $FindBin::Bin; 37 | 38 | say "-----------------------------------------------------------------------"; 39 | say "-------------------------------- Compiling ----------------------------"; 40 | say "-----------------------------------------------------------------------"; 41 | error if system 'make'; 42 | say "\n"; 43 | 44 | 45 | my %status; 46 | say "\n\n-----------------------------------------------------------------------"; 47 | say "---------------------- Correctness verifications ----------------------"; 48 | say "-----------------------------------------------------------------------\n\n"; 49 | for my $test (glob('checks/correctness/*.pl')) { 50 | if (system("./$test 1 --samples $samples") != 0) { 51 | $status{$test} = 0; 52 | } else { 53 | $status{$test} = 1; 54 | } 55 | } 56 | 57 | say "\n\n-----------------------------------------------------------------------"; 58 | say "-------------------------------- Results ------------------------------"; 59 | say "-----------------------------------------------------------------------\n"; 60 | for (keys %status) { 61 | if ($status{$_} == 0) { 62 | say "failed.... $_"; 63 | } else { 64 | say "OK........ $_"; 65 | } 66 | } 67 | my $n_fails = grep { $status{$_} == 0 } keys %status; 68 | my $n_ok = grep { $status{$_} == 1 } keys %status; 69 | my $n_total = keys %status; 70 | 71 | print "\n"; 72 | printf " %2d / %d test%s failed.\n", $n_fails, $n_total, $n_fails > 1 ? "s" : " "; 73 | printf " %2d / %d test%s succeeded.\n", $n_ok, $n_total, $n_ok > 1 ? "s" : " "; 74 | print "\n"; 75 | error if ($n_fails > 0); 76 | -------------------------------------------------------------------------------- /scripts/dune: -------------------------------------------------------------------------------- 1 | (env 2 | (dev 3 | (flags 4 | (:standard -warn-error -A)))) 5 | -------------------------------------------------------------------------------- /scripts/run-selected.ml: -------------------------------------------------------------------------------- 1 | module String_Map = Map.Make (String) 2 | 3 | (* Edit this list if you want to execute usuba on 4 | * different files or with different options *) 5 | let files_map = 6 | [ 7 | ("ace.ua", "-V -interleave 2"); 8 | ("aes_mslice.ua", "-H"); 9 | ("aes_generic.ua", "-V"); 10 | ("ascon.ua", "-V -interleave 2"); 11 | ("rectangle.ua", "-H -interleave 2"); 12 | ] 13 | |> List.fold_left 14 | (fun acc (file, options) -> String_Map.add file options acc) 15 | String_Map.empty 16 | 17 | let absolute_dir dir = 18 | if String.starts_with ~prefix:"~" dir then 19 | Filename.concat (Unix.getenv "HOME") 20 | (String.sub dir 2 (String.length dir - 2)) 21 | else if Filename.is_relative dir then Filename.concat (Sys.getcwd ()) dir 22 | else dir 23 | 24 | let examples_dir = ref "~/usuba_benchs/examples/samples/usuba" 25 | let usuba_args = ref [] 26 | 27 | let specs = 28 | Arg.( 29 | align 30 | [ 31 | ("--path", Set_string examples_dir, " Path to the .ua files"); 32 | ( "--", 33 | Rest_all (fun l -> usuba_args := l), 34 | " Options that will be given to usubac" ); 35 | ]) 36 | 37 | let usage = 38 | Printf.sprintf 39 | "%s [OPTION...] \n\n\ 40 | Dump an usuba file at each step of normalisation and optimisation.\n\n\ 41 | Options:" 42 | Sys.argv.(0) 43 | 44 | let pp_sep ppf () = Format.fprintf ppf " " 45 | 46 | let flush_channel oc = 47 | let rec aux acc = 48 | match input_line oc with 49 | | l -> aux (l :: acc) 50 | | exception End_of_file -> String.concat "\n" (List.rev acc) 51 | in 52 | aux [] 53 | 54 | let () = 55 | Arg.parse specs (fun _ -> ()) usage; 56 | let usuba_args = !usuba_args in 57 | let dir = absolute_dir !examples_dir in 58 | let files = Sys.readdir dir in 59 | Array.iter 60 | (fun file -> 61 | match String_Map.find file files_map with 62 | | args -> ( 63 | let file = Filename.concat dir file in 64 | Format.eprintf "File: %s@." file; 65 | let cmd = 66 | Format.asprintf "dune exec -- usuba %s %a %s" file 67 | Format.( 68 | pp_print_list ~pp_sep (fun ppf s -> Format.fprintf ppf "%s" s)) 69 | usuba_args args 70 | in 71 | Format.eprintf "%s... @." cmd; 72 | let cmd_out = Unix.open_process_in cmd in 73 | 74 | let e = flush_channel cmd_out in 75 | match Unix.close_process_in cmd_out with 76 | | Unix.WEXITED 0 -> Format.eprintf " ok@." 77 | | _ -> Format.eprintf "Something went wrong: %s@." e) 78 | | exception Not_found -> ()) 79 | files 80 | -------------------------------------------------------------------------------- /scripts/run-selected.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec ocaml unix.cma $(dirname $0)/run-selected.ml "$@" 3 | -------------------------------------------------------------------------------- /src/ansi_terminal.ml: -------------------------------------------------------------------------------- 1 | type style = 2 | | Normal 3 | | FG_Black 4 | | FG_Red 5 | | FG_Green 6 | | FG_Yellow 7 | | FG_Default 8 | | BG_Default 9 | 10 | let close_tag = function 11 | | FG_Black | FG_Red | FG_Green | FG_Yellow | FG_Default -> FG_Default 12 | | BG_Default -> BG_Default 13 | | _ -> Normal 14 | 15 | let style_of_tag = function 16 | | Format.String_tag s -> ( 17 | match s with 18 | | "n" -> Normal 19 | | "fg_black" -> FG_Black 20 | | "fg_red" -> FG_Red 21 | | "fg_green" -> FG_Green 22 | | "fg_yellow" -> FG_Yellow 23 | | "fg_default" -> FG_Default 24 | | "bg_default" -> BG_Default 25 | | _ -> raise Not_found) 26 | | _ -> raise Not_found 27 | 28 | (* See https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters for some values *) 29 | let to_ansi_value = function 30 | | Normal -> "0" 31 | | FG_Black -> "30" 32 | | FG_Red -> "31" 33 | | FG_Green -> "32" 34 | | FG_Yellow -> "33" 35 | | FG_Default -> "39" 36 | | BG_Default -> "49" 37 | 38 | let ansi_tag = Printf.sprintf "\x1B[%sm" 39 | let start_mark_ansi_stag t = ansi_tag @@ to_ansi_value @@ style_of_tag t 40 | 41 | let stop_mark_ansi_stag t = 42 | ansi_tag @@ to_ansi_value @@ close_tag @@ style_of_tag t 43 | 44 | let add_ansi_marking formatter = 45 | let open Format in 46 | pp_set_mark_tags formatter true; 47 | let old_fs = pp_get_formatter_stag_functions formatter () in 48 | pp_set_formatter_stag_functions formatter 49 | { 50 | old_fs with 51 | mark_open_stag = start_mark_ansi_stag; 52 | mark_close_stag = stop_mark_ansi_stag; 53 | } 54 | -------------------------------------------------------------------------------- /src/assert_lang.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | open Basic_utils 4 | open Utils 5 | 6 | module Usuba0 = struct 7 | let is_usuba0 (prog : prog) : bool = true 8 | end 9 | 10 | module Usuba_norm = struct 11 | let check_var (var : var) : bool = match var with Var _ -> true | _ -> false 12 | 13 | let check_pat_e (p : var list) (e : expr) : bool = 14 | match e with Tuple l -> List.length l = List.length p | _ -> true 15 | 16 | let rec check_expr (e : expr) : bool = 17 | match e with 18 | | Const _ -> true 19 | | ExpVar v -> check_var v 20 | | Tuple l -> List.for_all check_expr l 21 | | Not e -> check_expr e 22 | | Shift (_, e, _) -> check_expr e 23 | | Log (_, x, y) -> check_expr x && check_expr y 24 | | Shuffle (v, _) -> check_var v 25 | | Arith (_, x, y) -> check_expr x && check_expr y 26 | | Fun (_, l) -> List.for_all check_expr l 27 | | Fun_v _ -> false 28 | | Fby _ -> raise (Not_implemented "Fby") 29 | | When (_, _, _) -> false 30 | | Merge (_, _) -> false 31 | 32 | let check_p (p : p) : bool = 33 | List.for_all (function (_, Array _), _ -> false | _ -> true) p 34 | 35 | let check_def (def : def) : bool = 36 | match def.node with 37 | | Single (vars, body) -> 38 | check_p def.p_in && check_p def.p_out && check_p vars 39 | && List.for_all 40 | (function 41 | | Eqn (p, e) -> 42 | List.for_all check_var p && check_expr e && check_pat_e p e 43 | | _ -> false) 44 | body 45 | | _ -> false 46 | 47 | let is_usuba_normalized (prog : prog) : bool = 48 | Usuba0.is_usuba0 prog && List.for_all check_def prog.nodes 49 | end 50 | -------------------------------------------------------------------------------- /src/backtrace.ml: -------------------------------------------------------------------------------- 1 | type t = string list 2 | 3 | let empty = [] 4 | let append s t = s :: t 5 | 6 | let pp ppf t = 7 | Format.fprintf ppf "@[Backtrace:@,%a@]" 8 | Usuba_pp.(List.pp_tree Usuba_pp.String.pp) 9 | t 10 | -------------------------------------------------------------------------------- /src/c_gen/runtimes/genC_standalone.ml: -------------------------------------------------------------------------------- 1 | open Usuba_AST 2 | open Basic_utils 3 | open Utils 4 | 5 | let bits_per_reg (prog : prog) (conf : Config.config) : int = 6 | match conf.archi with 7 | | Std -> ( 8 | let main = last prog.nodes in 9 | let typ = (List.hd main.p_in).vd_typ in 10 | match get_type_dir typ with 11 | | Vslice -> ( 12 | match get_type_m (List.hd main.p_in).vd_typ with 13 | | Mint x -> x 14 | | _ -> assert false) 15 | | _ -> conf.bits_per_reg) 16 | | _ -> default_bits_per_reg conf.archi 17 | 18 | let gen_runtime (orig : prog) (prog : prog) (conf : Config.config) 19 | (filename : string) : string = 20 | let entry = 21 | (* STDLIB_IMPORT: Comparing to an empty string *) 22 | if Stdlib.(conf.fdti <> "") then 23 | List.( 24 | Nodes_to_c_fdti.def_to_c 25 | (nth prog.nodes (length prog.nodes - 1)) 26 | conf.arr_entry conf) 27 | else if conf.masked then 28 | List.( 29 | Nodes_to_c_masked.def_to_c 30 | (nth prog.nodes (length prog.nodes - 1)) 31 | conf.arr_entry conf) 32 | else if conf.ua_masked then 33 | List.( 34 | Nodes_to_c_ua_masked.def_to_c 35 | (nth prog.nodes (length prog.nodes - 1)) 36 | conf.arr_entry conf) 37 | else 38 | List.( 39 | Nodes_to_c.def_to_c 40 | (nth prog.nodes (length prog.nodes - 1)) 41 | conf.arr_entry conf) 42 | in 43 | let prog_c = 44 | (* STDLIB_IMPORT: Comparing to an empty string *) 45 | if Stdlib.(conf.fdti <> "") then 46 | map_no_end (fun x -> Nodes_to_c_fdti.def_to_c x false conf) prog.nodes 47 | else if conf.masked then 48 | map_no_end (fun x -> Nodes_to_c_masked.def_to_c x false conf) prog.nodes 49 | else if conf.ua_masked then 50 | map_no_end 51 | (fun x -> Nodes_to_c_ua_masked.def_to_c x false conf) 52 | prog.nodes 53 | else map_no_end (fun x -> Nodes_to_c.def_to_c x false conf) prog.nodes 54 | in 55 | 56 | let bench_fun = 57 | if conf.gen_bench then 58 | if conf.masked then Nodes_to_c_masked.gen_bench (last prog.nodes) conf 59 | else if conf.ua_masked then 60 | Nodes_to_c_ua_masked.gen_bench (last prog.nodes) conf 61 | else Nodes_to_c.gen_bench (last prog.nodes) conf 62 | else "" 63 | in 64 | 65 | Format.asprintf 66 | "/* This code was generated by Usuba.\n\ 67 | \ See https://github.com/DadaIsCrazy/usuba.\n\ 68 | \ From the file \"%s\" (included below). */\n\n\ 69 | #include \n\n\ 70 | /* Do NOT change the order of those define/include */\n\ 71 | %s\n\ 72 | #ifndef BITS_PER_REG\n\ 73 | #define BITS_PER_REG %d\n\ 74 | #endif\n\ 75 | /* including the architecture specific .h */\n\ 76 | #include \"%s\"\n\n\ 77 | /* auxiliary functions */\n\ 78 | %s\n\n\ 79 | /* main function */\n\ 80 | %s\n\n\ 81 | /* Additional functions */\n\ 82 | %s\n\n\ 83 | /* **************************************************************** */\n\ 84 | /* Usuba source */\n\ 85 | /* */\n\ 86 | /*\n\n\ 87 | %a\n\n\ 88 | */\n\ 89 | \ " filename 90 | (if conf.shares <> 1 then 91 | Printf.sprintf "#define MASKING_ORDER %d" conf.shares 92 | else "") 93 | (bits_per_reg prog conf) 94 | (* STDLIB_IMPORT: Comparing to an empty string *) 95 | (if Stdlib.(conf.fdti <> "") then Nodes_to_c_fdti.c_header conf.archi 96 | else if conf.masked then Nodes_to_c_masked.c_header conf.archi 97 | else if conf.ua_masked then Nodes_to_c_ua_masked.c_header conf.archi 98 | else Nodes_to_c.c_header conf.archi) 99 | (join "\n\n" prog_c) entry bench_fun (Usuba_print.pp_prog ()) orig 100 | -------------------------------------------------------------------------------- /src/c_gen/usuba_to_c.ml: -------------------------------------------------------------------------------- 1 | open Usuba_AST 2 | 3 | let prog_to_c (orig : prog) (normed : prog) (conf : Config.config) 4 | (filename : string) : string = 5 | (* let prog = if conf.interleave > 0 then *) 6 | (* Interleave.interleave normed conf *) 7 | (* else normed in *) 8 | GenC_standalone.gen_runtime orig normed conf filename 9 | -------------------------------------------------------------------------------- /src/clear_origins.ml: -------------------------------------------------------------------------------- 1 | (* **************************************************************** 2 | clear_origins.ml 3 | 4 | This module removes all origins from the programs: 5 | 6 | - all var_d's vd_orig fields are set to [] 7 | 8 | - all deq's orig fields are set to []. 9 | *) 10 | 11 | open Prelude 12 | open Usuba_AST 13 | 14 | let rec clear_deqs (deqs : deq list) : deq list = 15 | List.map 16 | (fun d -> 17 | { 18 | orig = []; 19 | content = 20 | (match d.content with 21 | | Eqn _ -> d.content 22 | | Loop t -> Loop { t with body = clear_deqs t.body }); 23 | }) 24 | deqs 25 | 26 | let clear_vd (vd : var_d) : var_d = { vd with vd_orig = [] } 27 | 28 | let clear_def (def : def) : def = 29 | let p_in = List.map clear_vd def.p_in in 30 | let p_out = List.map clear_vd def.p_out in 31 | { 32 | def with 33 | p_in; 34 | p_out; 35 | node = 36 | (match def.node with 37 | | Single (vars, body) -> 38 | let vars = List.map clear_vd vars in 39 | let body = clear_deqs body in 40 | Single (vars, body) 41 | | _ -> def.node); 42 | } 43 | 44 | let run _ prog _ = { nodes = List.map clear_def prog.nodes } 45 | let as_pass = (run, "Clear_origins", 0) 46 | -------------------------------------------------------------------------------- /src/dune: -------------------------------------------------------------------------------- 1 | (include_subdirs unqualified) 2 | 3 | (documentation 4 | (package usuba_lib)) 5 | 6 | (library 7 | (name Usuba_lib) 8 | (public_name usuba_lib) 9 | ; external dependencies 10 | (libraries unix str usuba_pp sexplib ppx_sexp_conv menhirLib) 11 | ; Specifying modules one by one because we don't want to include them all 12 | (modules 13 | prelude 14 | ; assert_lang 15 | ident 16 | ansi_terminal 17 | basic_utils 18 | clear_origins 19 | config 20 | interp 21 | pass_runner 22 | perfs 23 | rename 24 | usuba_AST 25 | syntax 26 | usuba_print 27 | utils 28 | ; maskverif 29 | usuba_to_maskverif 30 | ; optimization 31 | CSE 32 | constant_folding 33 | copy_propagation 34 | fuse_loop_general 35 | fuse_loops 36 | get_live_var 37 | inline 38 | inline_core 39 | interleave 40 | linearize_arrays 41 | pre_schedule 42 | remove_dead_code 43 | scheduler 44 | share_var 45 | simple_opts 46 | vital_inline 47 | ; tightprove 48 | print_tp 49 | tightprove 50 | tightprove_to_usuba 51 | tp_AST 52 | tp_IO 53 | usuba_to_tightprove 54 | ; tightprove/parsing 55 | lexer_tp 56 | parser_api_tp 57 | parser_tp 58 | ; verification 59 | ; bdd_verif 60 | soundness 61 | variable_binding 62 | type_checker 63 | ; c_gen 64 | nodes_to_c_fdti 65 | nodes_to_c_masked 66 | nodes_to_c 67 | nodes_to_c_ua_masked 68 | usuba_to_c 69 | ; c_gen/runtimes 70 | genC_standalone 71 | ; normalization 72 | clean 73 | expand_array 74 | expand_parameters 75 | init_scheduler 76 | monomorphize 77 | normalize_inner_core 78 | norm_tuples 79 | sbox_index 80 | unfold_unnest 81 | convert_tables 82 | expand_multiples 83 | expand_permut 84 | fix_dim 85 | mask 86 | normalize_core 87 | normalize 88 | remove_sync 89 | shift_tuples 90 | unroll 91 | ; parsing 92 | lexer 93 | backtrace 94 | errors 95 | parser_api 96 | parser_helper 97 | parser 98 | parser_messages) 99 | (inline_tests) 100 | (preprocess 101 | (pps ppx_inline_test ppx_deriving.show ppx_deriving.eq ppx_sexp_conv))) 102 | 103 | (env 104 | (dev 105 | (flags 106 | (:standard -warn-error -A)))) 107 | -------------------------------------------------------------------------------- /src/ident.ml: -------------------------------------------------------------------------------- 1 | open Sexplib.Std 2 | 3 | type uid = int [@@deriving sexp] 4 | type t = { name : string; uid : uid; parent : t option } [@@deriving sexp] 5 | 6 | let equal t1 t2 = String.equal t1.name t2.name 7 | let hash { name; _ } = Hashtbl.hash name 8 | let compare t1 t2 = String.compare t1.name t2.name 9 | 10 | (* Getters *) 11 | 12 | let name { name; _ } = name 13 | let uid { uid; _ } = uid 14 | 15 | (* Parsing phase *) 16 | let create_unbound name = { name; uid = -1; parent = None } 17 | 18 | (* let create_constant = *) 19 | (* let counter = ref 0 in *) 20 | (* fun name -> *) 21 | (* decr counter; *) 22 | (* { name; uid = !counter } *) 23 | let create_constant name = { name; uid = -1; parent = None } 24 | 25 | (* Fresh idents *) 26 | 27 | let free_unbound, create_free = 28 | let counter = ref 0 in 29 | ( (fun t -> 30 | assert (t.uid = -1); 31 | incr counter; 32 | { t with uid = !counter }), 33 | fun name -> 34 | incr counter; 35 | { name; uid = !counter; parent = None } ) 36 | 37 | (* let create_free name = { name; uid = -1 } *) 38 | let fresh_suffixed { name; _ } suff = create_free (name ^ suff) 39 | let fresh_prefixed { name; _ } suff = create_free (suff ^ name) 40 | let fresh_concat t1 t2 = create_free (t1.name ^ t2.name) 41 | let fresh_copy { name; _ } = create_free name 42 | 43 | (* Copies *) 44 | let bound_copy id name = { id with name } 45 | let bound_copy2 id = { id with name = id.name ^ "__2" } 46 | let bound_copy3 id = { id with name = id.name ^ "__3" } 47 | 48 | (* Printers *) 49 | let rec pp ?(detailed = false) () ppf { name; uid; parent } = 50 | Format.fprintf ppf "%s%s" name 51 | (if detailed then 52 | Format.asprintf "(%d%a)" uid 53 | (fun ppf -> function 54 | | None -> () 55 | | Some parent -> Format.fprintf ppf " > %a" (pp ~detailed ()) parent) 56 | parent 57 | else "") 58 | 59 | let pp_create ppf t = 60 | Format.fprintf ppf {|(Ident.create_unbound "%a")|} (pp ()) t 61 | 62 | (* Collections *) 63 | 64 | module NameMap = struct 65 | include Map.Make (struct 66 | type t = string 67 | 68 | let compare = String.compare 69 | end) 70 | 71 | let pp ?(pp_sep = fun ppf () -> Format.fprintf ppf "; ") ?(left = "[") 72 | ?(right = "]") pp_v ppf t = 73 | Usuba_pp.List.pp ~pp_sep ~left ~right 74 | (fun ppf (k, v) -> 75 | Format.fprintf ppf "%a -> %a" Usuba_pp.String.pp k pp_v v) 76 | ppf (bindings t) 77 | end 78 | 79 | module Map = struct 80 | include Map.Make (struct 81 | type nonrec t = t 82 | 83 | let compare = compare 84 | end) 85 | 86 | let pp ?(pp_sep = fun ppf () -> Format.fprintf ppf "; ") ?(left = "[") 87 | ?(right = "]") pp_v ppf t = 88 | Usuba_pp.List.pp ~pp_sep ~left ~right 89 | (fun ppf (k, v) -> 90 | Format.fprintf ppf "%a -> %a" (pp ~detailed:true ()) k pp_v v) 91 | ppf (bindings t) 92 | end 93 | 94 | module Hashtbl = struct 95 | include Hashtbl.Make (struct 96 | type nonrec t = t 97 | 98 | let equal = equal 99 | let hash = hash 100 | end) 101 | 102 | (* Retrieving the keys of a hash *) 103 | let keys hash = fold (fun k _ acc -> k :: acc) hash [] 104 | 105 | (* Retrieving the values of a hash *) 106 | let values hash = fold (fun _ v acc -> v :: acc) hash [] 107 | 108 | (* Getting a list of keys,values *) 109 | let each hash = fold (fun k v acc -> (k, v) :: acc) hash [] 110 | 111 | (* Retrieving the keys of a HoH's 2nd layer*) 112 | let keys_2nd_layer hash k = try keys (find hash k) with Not_found -> [] 113 | end 114 | 115 | let bind ~backtrace map { name; _ } = 116 | match NameMap.find name map with 117 | | { uid; _ } as parent -> 118 | if uid = -1 then raise (Errors.Binding_to_unbound (name, backtrace)) 119 | else { name; uid; parent = Some parent } 120 | | exception Not_found -> raise (Errors.Binding_unknown (name, backtrace)) 121 | -------------------------------------------------------------------------------- /src/interp.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | 4 | (* Returns the local vars of |f|, or nothing if |f| doesn't have local 5 | variables. *) 6 | let get_vars (f : def) = match f.node with Single (vars, _) -> vars | _ -> [] 7 | 8 | module Usuba0 = struct 9 | let rec interp_expr env_fun (env_params : typ Ident.Hashtbl.t) 10 | (env_var : bool VarHashtbl.t) (e : expr) : bool list = 11 | let interp_expr_rec = interp_expr env_fun env_params env_var in 12 | match e with 13 | | Const (0, _) -> [ false ] 14 | | Const (1, _) -> [ true ] 15 | | ExpVar v -> [ VarHashtbl.find env_var v ] 16 | | Not e' -> List.map not (interp_expr_rec e') 17 | | Log (op, x, y) -> ( 18 | match op with 19 | | And -> List.map2 ( && ) (interp_expr_rec x) (interp_expr_rec y) 20 | | Or -> List.map2 ( || ) (interp_expr_rec x) (interp_expr_rec y) 21 | | Xor -> 22 | List.map2 23 | (fun x y -> (x && not y) || ((not x) && y)) 24 | (interp_expr_rec x) (interp_expr_rec y) 25 | | Andn -> 26 | List.map2 27 | (fun x y -> (not x) && y) 28 | (interp_expr_rec x) (interp_expr_rec y) 29 | | _ -> assert false) 30 | | Fun (f, l) -> 31 | let l' = List.flatten (List.map interp_expr_rec l) in 32 | let f' = Ident.Hashtbl.find env_fun f in 33 | interp_node env_fun f' l' 34 | | _ -> 35 | raise 36 | (Errors.Error 37 | (Format.asprintf "Invalid expression: %a" (Usuba_print.pp_expr ()) 38 | e)) 39 | 40 | and interp_node env_fun (f : def) (l : bool list) : bool list = 41 | (* the function to evaluate an assignment *) 42 | let interp_asgn env_fun (env_params : typ Ident.Hashtbl.t) 43 | (env_var : bool VarHashtbl.t) (vars : var list) (expr : expr) : unit = 44 | let res = interp_expr env_fun env_params env_var expr in 45 | List.iter2 46 | (fun x y -> VarHashtbl.replace env_var x y) 47 | (Basic_utils.flat_map (Utils.expand_var env_params) vars) 48 | res 49 | in 50 | (* creating a lexical environement *) 51 | let env_var : bool VarHashtbl.t = VarHashtbl.create 100 in 52 | (* adding the inputs in the environment *) 53 | let env_params = Utils.build_env_var f.p_in f.p_out (get_vars f) in 54 | List.iter2 55 | (fun v y -> VarHashtbl.replace env_var v y) 56 | (Basic_utils.flat_map 57 | (Utils.expand_var env_params) 58 | (Utils.p_to_vars f.p_in)) 59 | l; 60 | (* evaluating the instructions of the node *) 61 | (match f.node with 62 | | Single (_, deqs) -> 63 | List.iter 64 | (fun d -> 65 | match d.content with 66 | | Eqn (vars, e, _) -> interp_asgn env_fun env_params env_var vars e 67 | | _ -> raise (Errors.Error "Invalid 'Loop'")) 68 | deqs 69 | | _ -> 70 | raise 71 | (Errors.Error 72 | (Format.asprintf "Invalid node: %a" (Usuba_print.pp_def ()) f))); 73 | (* returning the values of the output variables *) 74 | List.map (VarHashtbl.find env_var) 75 | (Basic_utils.flat_map 76 | (Utils.expand_var env_params) 77 | (Utils.p_to_vars f.p_out)) 78 | 79 | let interp_prog (prog : prog) (input : bool list) : bool list = 80 | let env_fun = Ident.Hashtbl.create 100 in 81 | (* Collecting the list of nodes *) 82 | List.iter (fun f -> Ident.Hashtbl.replace env_fun f.id f) prog.nodes; 83 | (* Calling the last node (the entry point by convention) *) 84 | interp_node env_fun (Basic_utils.last prog.nodes) input 85 | end 86 | 87 | module Usuba = struct 88 | (* Note: node is a Table *) 89 | let interp_table (node : def) (l : bool list) : bool list = 90 | let idx = Basic_utils.boollist_to_int l in 91 | match node.node with 92 | | Table tbl -> 93 | Basic_utils.int_to_boollist (List.nth tbl idx) (Utils.p_size node.p_out) 94 | | _ -> assert false 95 | end 96 | -------------------------------------------------------------------------------- /src/normalization/clean.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | 4 | (* Clean.clean_vars_decl removes unused variables from variable declarations of nodes 5 | (unused variables will likely be variables that have been optimized out) *) 6 | let rec collect_var env (var : var) : unit = 7 | match var with 8 | | Var id -> Ident.Hashtbl.replace env id 1 9 | | Index (v, _) | Range (v, _, _) | Slice (v, _) -> collect_var env v 10 | 11 | let rec collect_expr env (e : expr) : unit = 12 | match e with 13 | | Const _ -> () 14 | | ExpVar v -> collect_var env v 15 | | Tuple l -> List.iter (collect_expr env) l 16 | | Not e -> collect_expr env e 17 | | Log (_, x, y) -> 18 | collect_expr env x; 19 | collect_expr env y 20 | | Arith (_, x, y) -> 21 | collect_expr env x; 22 | collect_expr env y 23 | | Shift (_, x, _) -> collect_expr env x 24 | | Shuffle (v, _) -> collect_var env v 25 | | Bitmask (e, _) -> collect_expr env e 26 | | Pack (e1, e2, _) -> 27 | collect_expr env e1; 28 | collect_expr env e2 29 | | Fun (_, l) -> List.iter (collect_expr env) l 30 | | Fun_v (_, _, l) -> List.iter (collect_expr env) l 31 | 32 | let clean_in_deqs (vars : p) (deqs : deq list) : p = 33 | let env = Ident.Hashtbl.create 100 in 34 | let rec aux d = 35 | match d.content with 36 | | Eqn (l, e, _) -> 37 | List.iter (collect_var env) l; 38 | collect_expr env e 39 | | Loop { body; _ } -> List.iter aux body 40 | in 41 | List.iter aux deqs; 42 | List.sort_uniq compare_var_d 43 | (List.filter 44 | (fun vd -> 45 | match Ident.Hashtbl.find_opt env vd.vd_id with 46 | | Some _ -> true 47 | | None -> false) 48 | vars) 49 | 50 | let clean_def (def : def) : def = 51 | match def.node with 52 | | Single (vars, body) -> 53 | let vars = clean_in_deqs vars body in 54 | { def with node = Single (vars, body) } 55 | | _ -> def 56 | 57 | let run _ prog _ = { nodes = List.map clean_def prog.nodes } 58 | let as_pass = (run, "Clean", 0) 59 | -------------------------------------------------------------------------------- /src/normalization/expand_multiples.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | 4 | let run _ prog _ = 5 | { 6 | nodes = 7 | Basic_utils.flat_map 8 | (fun def -> 9 | match def.node with 10 | | Multiple l -> 11 | List.mapi 12 | (fun i x -> 13 | { 14 | def with 15 | id = Ident.fresh_suffixed def.id (Printf.sprintf "%d'" i); 16 | node = x; 17 | }) 18 | l 19 | | _ -> [ def ]) 20 | prog.nodes; 21 | } 22 | 23 | let as_pass = (run, "Expand_multiples", 0) 24 | -------------------------------------------------------------------------------- /src/normalization/expand_permut.ml: -------------------------------------------------------------------------------- 1 | (***************************************************************************** ) 2 | expand_permut.ml 3 | 4 | This module converts permutation tables into regular nodes. 5 | 6 | This is actually a temporary solution, as we'd rather like the permutation 7 | tables to just rename registers. 8 | 9 | After this module has ran, there souldn't be any "MultiplePerm" left. 10 | 11 | ( *****************************************************************************) 12 | 13 | open Prelude 14 | open Usuba_AST 15 | open Basic_utils 16 | open Utils 17 | 18 | let list_from_perm env_var (perm : int list) (l : expr list) : expr list = 19 | let args = Array.of_list (flat_map (Unfold_unnest.expand_expr env_var) l) in 20 | List.map (fun i -> args.(i - 1)) perm 21 | 22 | let rec apply_perm_e env_fun env_var (e : expr) : expr = 23 | match e with 24 | | Const _ | ExpVar _ | Shuffle _ -> e 25 | | Tuple l -> Tuple (List.map (apply_perm_e env_fun env_var) l) 26 | | Not e -> Not (apply_perm_e env_fun env_var e) 27 | | Log (op, x, y) -> 28 | Log (op, apply_perm_e env_fun env_var x, apply_perm_e env_fun env_var y) 29 | | Arith (op, x, y) -> 30 | Arith (op, apply_perm_e env_fun env_var x, apply_perm_e env_fun env_var y) 31 | | Shift (op, e, n) -> Shift (op, apply_perm_e env_fun env_var e, n) 32 | | Bitmask (e, ae) -> Bitmask (apply_perm_e env_fun env_var e, ae) 33 | | Pack (e1, e2, t) -> 34 | Pack (apply_perm_e env_fun env_var e1, apply_perm_e env_fun env_var e2, t) 35 | | Fun (f, l) -> ( 36 | let l' = List.map (apply_perm_e env_fun env_var) l in 37 | match env_fetch env_fun f with 38 | | Some perm -> Tuple (list_from_perm env_var perm l') 39 | | None -> Fun (f, l')) 40 | | Fun_v (_, _, _) -> assert false 41 | 42 | let apply_perm env_fun env_var (deqs : deq list) : deq list = 43 | List.map 44 | (fun d -> 45 | match d.content with 46 | | Eqn (p, e, sync) -> 47 | { d with content = Eqn (p, apply_perm_e env_fun env_var e, sync) } 48 | | _ -> d) 49 | deqs 50 | 51 | let rewrite_defs (l : def list) : def list = 52 | let env_fun = Hashtbl.create 10 in 53 | List.iter 54 | (fun x -> match x.node with Perm l -> env_add env_fun x.id l | _ -> ()) 55 | l; 56 | List.map 57 | (fun x -> 58 | match x.node with 59 | | Single (vars, body) -> 60 | let env_var = build_env_var x.p_in x.p_out vars in 61 | { x with node = Single (vars, apply_perm env_fun env_var body) } 62 | | _ -> x) 63 | l 64 | 65 | let run _ p _ = 66 | { 67 | nodes = 68 | List.filter 69 | (fun x -> match x.node with Perm _ -> false | _ -> true) 70 | (rewrite_defs p.nodes); 71 | } 72 | 73 | let as_pass = (run, "Expand_permut", 0) 74 | -------------------------------------------------------------------------------- /src/normalization/fix_all_params.ml: -------------------------------------------------------------------------------- 1 | (* Abandonning for now due to: 2 | je veux bien ton avis sur un truc: j'ai un noeud `f : b32[4] -> ...`, et je lui passe en argument un `b128`. Pour le moment, usubac se demerde pour que les 2 matchent (`b128` = 1 argument; `b32[4]` = 4 arguments). Du coup, le noeud se retrouve transformé en `f: b1[128]` et son paramètre devient un `b1[128]` également. Le truc, c'est que ca me force à inliner l'appel de fonction (parce que sinon, 128 paramètres pour un appel de fonction; bof), et ca force potentiellement une expansion des paramètres que je n'aime pas. Un truc qui serait envisable, c'est que usubac garde les mêmes types `b32[4]` et `b128`, parce que en C, si t'as `x: bool[128]`, alors tu peux faire `x0=x, x1=&x[32],x2=&x[64],x3=&x[96]` et t'as tes `x:bool* =~ bool[32]` et donc tout se goupille bien. Sauf que du coup ca fait des trucs étranges dans Usuba : ca devient quoi le type du premier param de `f` (appelons le `x`) ? ca ne peut pas rester `x:b32[4]`, parce que dans ce cas, son premier élément sera `x[0][0]` et son 32e `x[1][0]` alors qu'ils devraient etre respectivement `x[0]` et `x[32]`. Si du coup on essaye de donner `b128` comme type à `x`, alors par quoi tu remplace `x[1]`, qui avait pour type `b32` devient désormais quelque chose que `x[32]`, mais qui a pour type `b1` et non `b128` (en C, tu aurais remplacé `x[1]` par `&x[32]` qui a donc pour type `bool* =~ bool[32]`, mais pas vraiment faisable dans Usuba). Any thoughts? on peut en parler en physique si c'est plus simple 3 | *) 4 | 5 | open Usuba_AST 6 | open Basic_utils 7 | open Utils 8 | 9 | let stable = ref false 10 | 11 | 12 | 13 | let rec match_lists (env_var:(ident, typ) Hashtbl.t) 14 | (expect:p) (given:var list) = 15 | match expect, given with 16 | | hd_e::tl_e, hd_g::tl_g -> 17 | let typ_e = hd_e.vd_typ in 18 | let typ_g = get_var_type env_var hd_g in 19 | if typ_e = typ_g then 20 | 21 | | _ -> assert false 22 | 23 | let fix_funcall (env_fun:(ident,def) Hashtbl.t) 24 | (env_var:(ident, typ) Hashtbl.t) 25 | (lhs:var list) 26 | (id:ident) 27 | (args:expr list) 28 | (sync:bool) : deq = 29 | let f = Hashtbl.find env_fun id in 30 | 31 | (* args can only be variables *) 32 | let args = List.map (function ExpVar v -> v | _ -> assert false) args in 33 | 34 | 35 | 36 | 37 | let rec fix_deq (env_fun:(ident,def) Hashtbl.t) 38 | (env_var:(ident, typ) Hashtbl.t) 39 | (deqs:deq) : deq = 40 | match deq with 41 | | Eqn(lhs,Fun(id,args),sync) -> 42 | if id.name = "rand" then deq 43 | else fix_funcall env_fun env_var lhs id args sync 44 | | Eqn _ -> deq 45 | | Loop(i,ei,ef,dl,opts) -> 46 | Hashtbl.add env_var i Nat; 47 | let new_deq = Loop(i,ei,ef,List.map (fix_deq env_fun env_var) dl,opts) in 48 | Hashtbl.remove env_var i; 49 | new_deq 50 | 51 | 52 | let fix_def (env_fun:(ident,def) Hashtbl.t) (def:def) : unit = 53 | match def.node with 54 | | Single(vars,body) -> 55 | let env_var = build_env_var def.p_in def.p_out vars in 56 | let body = List.map (fix_deq env_fun env_var) body in 57 | Hashtbl.replace env_fun def.id { def with node = Single(vars,body) } 58 | | _ -> () 59 | 60 | 61 | let fix_prog (prog:prog) (conf:config) : prog = 62 | 63 | let env_fun = Hashtbl.create 100 in 64 | List.iter (fun node -> Hashtbl.add env_fun node.id node) prog.nodes; 65 | 66 | stable := false; 67 | while not !stable do 68 | stable := true; 69 | List.iter (fun node -> fix_def env_fun (Hashtbl.find env_fun node.id)) prog.nodes 70 | done; 71 | 72 | { nodes = List.map (fun node -> Hashtbl.find env_fun node.id) prog.nodes } 73 | 74 | -------------------------------------------------------------------------------- /src/normalization/normalize_core.ml: -------------------------------------------------------------------------------- 1 | open Usuba_AST 2 | open Pass_runner 3 | 4 | let run (runner : pass_runner) (prog : prog) _ = 5 | runner#run_modules 6 | [ 7 | Expand_array.as_pass; 8 | Normalize_inner_core.as_pass; 9 | Expand_parameters.as_pass; 10 | Fix_dim.Dir_params.as_pass; 11 | Expand_array.as_pass; 12 | Normalize_inner_core.as_pass; 13 | Expand_parameters.as_pass; 14 | Fix_dim.Dir_inner.as_pass; 15 | Expand_array.as_pass; 16 | Normalize_inner_core.as_pass; 17 | ] 18 | prog 19 | 20 | let as_pass = (run, "Normalize_core", 1) 21 | -------------------------------------------------------------------------------- /src/normalization/normalize_inner_core.ml: -------------------------------------------------------------------------------- 1 | open Usuba_AST 2 | open Pass_runner 3 | 4 | let run (runner : pass_runner) (prog : prog) _ : prog = 5 | runner#run_modules 6 | [ 7 | Unfold_unnest.as_pass; 8 | Expand_array.as_pass; 9 | Expand_permut.as_pass; 10 | Norm_tuples.as_pass; 11 | Shift_tuples.as_pass; 12 | Norm_tuples.as_pass; 13 | ] 14 | prog 15 | 16 | let as_pass = (run, "Normalize_inner_core", 1) 17 | -------------------------------------------------------------------------------- /src/optimization/get_live_var.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | 4 | let rec add_right env_var live e = 5 | match e with 6 | | Const _ -> () 7 | | ExpVar v -> 8 | List.iter 9 | (fun v -> VarHashtbl.replace live (Utils.get_var_base v) true) 10 | (Utils.expand_var env_var v) 11 | | Tuple l -> List.iter (add_right env_var live) l 12 | | Not e -> add_right env_var live e 13 | | Shift (_, e, _) -> add_right env_var live e 14 | | Log (_, x, y) -> 15 | add_right env_var live x; 16 | add_right env_var live y 17 | | Shuffle (v, _) -> 18 | List.iter 19 | (fun v -> VarHashtbl.replace live (Utils.get_var_base v) true) 20 | (Utils.expand_var env_var v) 21 | | Arith (_, x, y) -> 22 | add_right env_var live x; 23 | add_right env_var live y 24 | | Bitmask (e', _) -> add_right env_var live e' 25 | | Pack (e1, e2, _) -> 26 | add_right env_var live e1; 27 | add_right env_var live e2 28 | | Fun (_, l) -> List.iter (add_right env_var live) l 29 | | _ -> assert false 30 | 31 | let remove_left env_var live lhs = 32 | List.iter 33 | (fun v -> 34 | List.iter 35 | (fun v -> VarHashtbl.remove live (Utils.get_var_base v)) 36 | (Utils.expand_var env_var v)) 37 | lhs 38 | 39 | let live_deq env_var live (deq : deq) : int = 40 | let nb_live = VarHashtbl.length live in 41 | (match deq.content with 42 | | Eqn (lhs, rhs, _) -> 43 | add_right env_var live rhs; 44 | remove_left env_var live lhs 45 | | Loop _ -> raise (Errors.Not_implemented "live_deq(Loop ...)")); 46 | (* Printf.printf "[%3d -> %3d] %s\n" nb_live (Hashtbl.length live) (Usuba_print.deq_to_str deq); *) 47 | nb_live 48 | 49 | let live_deqs env_var (p_out : p) (deqs : deq list) : int = 50 | let live = VarHashtbl.create 50 in 51 | List.iter 52 | (fun x -> 53 | List.iter 54 | (fun x -> VarHashtbl.add live x true) 55 | (Utils.expand_var env_var (Var x.vd_id))) 56 | p_out; 57 | 58 | Basic_utils.max_l (List.map (live_deq env_var live) (List.rev deqs)) 59 | 60 | let live_def (def : def) : int = 61 | match def.node with 62 | | Single (vars, body) -> ( 63 | let env_var = Utils.build_env_var def.p_in def.p_out vars in 64 | try live_deqs env_var def.p_out body with Errors.Not_implemented _ -> -1) 65 | | _ -> -1 66 | 67 | let get_live_var (prog : prog) : int = 68 | Basic_utils.max_l (List.map live_def prog.nodes) 69 | -------------------------------------------------------------------------------- /src/optimization/optimize.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Basic_utils 3 | open Utils 4 | open Usuba_AST 5 | open Usuba_print 6 | open Pass_runner 7 | 8 | let optimize (runner : pass_runner) (prog : Usuba_AST.prog) (conf : config) : 9 | Usuba_AST.prog = 10 | runner#run_modules_bench 11 | [ 12 | ( Interleave.as_pass, 13 | conf.interleave > 0, 14 | Pass_runner.Custom conf.bench_inter ); 15 | (Simple_opts.as_pass, true, Pass_runner.Always); 16 | (Fuse_loop_general.as_pass, conf.loop_fusion, Pass_runner.Always); 17 | (Simple_opts.as_pass, true, Pass_runner.Always); 18 | (Scheduler.as_pass, conf.scheduling, Pass_runner.Toggle conf.bench_msched); 19 | (Share_var.as_pass, conf.share_var, Pass_runner.Toggle conf.bench_sharevar); 20 | (Clean.as_pass, true, Pass_runner.Always); 21 | (Remove_dead_code.as_pass, true, Pass_runner.Always); 22 | ] 23 | prog 24 | 25 | let as_pass = ((optimize, "Optimize"), 1) 26 | -------------------------------------------------------------------------------- /src/optimization/simple_opts.ml: -------------------------------------------------------------------------------- 1 | (******************************************************************* ) 2 | simple_opts.ml 3 | 4 | This module just runs basic optimisations: 5 | - Constant Folding 6 | - Common Subexpression Elimination 7 | - Copy Propagation 8 | 9 | If I implement loop-invariant code motion, it will be ran here as 10 | well. 11 | 12 | 13 | ( ***************************************************************** *) 14 | 15 | open Prelude 16 | open Usuba_AST 17 | open Pass_runner 18 | 19 | let rec opt_def ?(retry : int = 5) (def : def) = 20 | let def' = 21 | Norm_tuples.norm_tuples_def 22 | (Copy_propagation.cp_def (CSE.cse_def (Constant_folding.fold_def def))) 23 | in 24 | 25 | if retry > 0 then 26 | if equal_def def def' then def else opt_def ~retry:(retry - 1) def' 27 | else def' 28 | 29 | let rec _run (runner : pass_runner) ?(retry : int = 20) (prog : prog) 30 | (conf : Config.config) : prog = 31 | let prog' = 32 | runner#run_modules_guard 33 | [ 34 | (Constant_folding.as_pass, conf.fold_const); 35 | (CSE.as_pass, conf.cse); 36 | (Copy_propagation.as_pass, conf.copy_prop); 37 | (Norm_tuples.as_pass, true); 38 | ] 39 | prog 40 | in 41 | 42 | if retry > 0 then 43 | if equal_prog prog prog' then prog 44 | else _run runner ~retry:(retry - 1) prog' conf 45 | else prog' 46 | 47 | let run (runner : pass_runner) (prog : prog) (conf : Config.config) : prog = 48 | _run runner prog conf 49 | 50 | let as_pass = (run, "Simple_opts", 1) 51 | -------------------------------------------------------------------------------- /src/optimization/vital_inline.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | open Utils 4 | open Inline_core 5 | 6 | (* This module checks if a node _must_ be inlined and if so, returns 7 | it. For now, a node must be inlined if it uses shifts of sizes 8 | depending on the parameters. *) 9 | module Must_inline = struct 10 | let rec contains_in (env_in : bool Ident.Hashtbl.t) (ae : arith_expr) : bool = 11 | match ae with 12 | | Const_e _ -> false 13 | | Var_e v -> Ident.Hashtbl.mem env_in v 14 | | Op_e (_, x, y) -> contains_in env_in x || contains_in env_in y 15 | 16 | (* |e| is a variable that is being shifted. Need to check if it's a 17 | tuple, or it's dir is Bitslice. *) 18 | (* TODO: this should be done somewhere else / some other way. *) 19 | let must_inline_shift (env_var : typ Ident.Hashtbl.t) 20 | (env_in : bool Ident.Hashtbl.t) (e : expr) (ae : arith_expr) : bool = 21 | contains_in env_in ae 22 | && 23 | match e with 24 | | Tuple _ -> true 25 | | _ -> 26 | (* Note that at this point, there is a chance that we are 27 | bitslicing but Monomorphize hasn't ran already. In this case, 28 | this will return false, but we don't care, as later call to 29 | this module will work correctly. *) 30 | equal_dir (get_normed_expr_dir env_var e) Bslice 31 | 32 | let rec must_inline_expr (env_var : typ Ident.Hashtbl.t) 33 | (env_in : bool Ident.Hashtbl.t) (e : expr) : bool = 34 | match e with 35 | | Const _ -> false 36 | | ExpVar _ -> false 37 | | Tuple l -> List.exists (must_inline_expr env_var env_in) l 38 | | Not e' -> must_inline_expr env_var env_in e' 39 | | Log (_, x, y) -> 40 | must_inline_expr env_var env_in x || must_inline_expr env_var env_in y 41 | | Arith (_, x, y) -> 42 | must_inline_expr env_var env_in x || must_inline_expr env_var env_in y 43 | | Shift (_, e', ae) -> 44 | must_inline_expr env_var env_in e' 45 | || must_inline_shift env_var env_in e' ae 46 | | Shuffle _ -> false 47 | | Bitmask (e', _) -> must_inline_expr env_var env_in e' 48 | | Pack (e1, e2, _) -> 49 | must_inline_expr env_var env_in e1 || must_inline_expr env_var env_in e2 50 | | Fun (_, l) -> List.exists (must_inline_expr env_var env_in) l 51 | | Fun_v (_, _, l) -> List.exists (must_inline_expr env_var env_in) l 52 | 53 | let rec must_inline_deqs (env_var : typ Ident.Hashtbl.t) 54 | (env_in : bool Ident.Hashtbl.t) (deqs : deq list) : bool = 55 | List.exists 56 | (fun d -> 57 | match d.content with 58 | | Eqn (_, e, _) -> must_inline_expr env_var env_in e 59 | | Loop { body; _ } -> must_inline_deqs env_var env_in body) 60 | deqs 61 | 62 | let must_inline_def (def : def) : bool = 63 | match def.node with 64 | | Single (vars, body) -> 65 | let env_var = build_env_var def.p_in def.p_out vars in 66 | let env_in = Ident.Hashtbl.create 10 in 67 | List.iter (fun vd -> Ident.Hashtbl.add env_in vd.vd_id true) def.p_in; 68 | must_inline_deqs env_var env_in body 69 | | _ -> false 70 | 71 | let must_inline (prog : prog) : def option = 72 | List.find_opt must_inline_def prog.nodes 73 | end 74 | 75 | (* Inlines only the functions that must be inlined. For now, those are 76 | functions that use tuple shifts with a shift size depending on a 77 | parameter *) 78 | let rec vital_inline (prog : prog) (conf : Config.config) : prog = 79 | match Must_inline.must_inline prog with 80 | | None -> prog 81 | | Some node -> ( try vital_inline (do_inline prog node) conf with _ -> prog) 82 | (* Program not normalized -> can't inline now *) 83 | -------------------------------------------------------------------------------- /src/parsing/dune: -------------------------------------------------------------------------------- 1 | (ocamllex 2 | (modules lexer)) 3 | 4 | (menhir 5 | (modules parser) 6 | (flags --table)) 7 | 8 | (rule 9 | (targets parser_messages.ml) 10 | (deps parser.messages parser.mly) 11 | (action 12 | (with-stdout-to 13 | %{targets} 14 | (run menhir --compile-errors %{deps})))) 15 | -------------------------------------------------------------------------------- /src/parsing/parser_helper.ml: -------------------------------------------------------------------------------- 1 | module I = Parser.MenhirInterpreter 2 | 3 | let get_parse_error env = 4 | match I.stack env with 5 | | (lazy Nil) -> "Invalid syntax" 6 | | (lazy (Cons (I.Element (state, _, _, _), _))) -> ( 7 | try Parser_messages.message (I.number state) 8 | with Not_found -> "invalid syntax (no specific message for this error)") 9 | -------------------------------------------------------------------------------- /src/perfs.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | 4 | (* Number of times to repeat benchmarks when comparing several programs *) 5 | let repeat = 30 6 | 7 | let bench_code = 8 | "#include \n\ 9 | #include \n\ 10 | #include \n\ 11 | #include \n\n\ 12 | #ifndef NB_RUN\n\ 13 | #define NB_RUN 10000000\n\ 14 | #endif\n\n\ 15 | #ifndef WARMING\n\ 16 | #define WARMING 1000\n\ 17 | #endif\n\n\ 18 | uint32_t bench_speed();\n\n\ 19 | int main() {\n\n\ 20 | \ /* Getting number of encrypted bytes */\n\ 21 | \ uint64_t encrypted = bench_speed();\n\n\ 22 | \ /* Warming up caches */\n\ 23 | \ for (int i = 0; i < WARMING; i++)\n\ 24 | \ bench_speed();\n\n\ 25 | \ /* The actual benchmark */\n\ 26 | \ unsigned int garbage;\n\ 27 | \ uint64_t timer = __rdtscp(&garbage);\n\ 28 | \ for (int i = 0; i < NB_RUN; i++)\n\ 29 | \ bench_speed();\n\ 30 | \ timer = __rdtscp(&garbage) - timer;\n\n\ 31 | \ /* Printing the result */\n\ 32 | \ printf(\"%.2f\", (double)timer / (NB_RUN * encrypted));\n\ 33 | }" 34 | 35 | (* Returns the name of the executable generated for |prog|. *) 36 | let compile (arch : Config.arch) (bitslice : bool) (prog : prog) : string = 37 | let conf = { Utils.default_conf with gen_bench = true; archi = arch } in 38 | let c_prog = GenC_standalone.gen_runtime prog prog conf "" in 39 | 40 | let bin_filename = Filename.temp_file "usuba-perf-bench" "" in 41 | let c_filename = bin_filename ^ ".c" in 42 | let out = open_out c_filename in 43 | 44 | Printf.fprintf out "%s\n\n%s" bench_code c_prog; 45 | close_out out; 46 | 47 | let compile_cmd = 48 | Printf.sprintf 49 | "clang -O3 -march=native -fno-tree-vectorize -fno-slp-vectorize -D \ 50 | NB_RUN=%d -I %s %s -o %s" 51 | (if bitslice then 100_000 else 1_000_000) 52 | Config.arch_dir c_filename bin_filename 53 | in 54 | ignore (Sys.command compile_cmd); 55 | 56 | bin_filename 57 | 58 | (* Runs |bin|, reads its performance on its stdout, and returns it. *) 59 | let get_perf (bin : string) : float = 60 | let in_chan = Unix.open_process_in bin in 61 | let res = float_of_string (input_line in_chan) in 62 | ignore (Unix.close_process_in in_chan); 63 | res 64 | 65 | (* Removes the first and last two elements from *) 66 | let remove_start_end (l : 'a list) : 'a list = 67 | let rec remove_start l n = 68 | if n == 0 then l else remove_start (List.tl l) (n - 1) 69 | in 70 | let remove_end l n = List.rev (remove_start (List.rev l) n) in 71 | remove_start (remove_end l 2) 2 72 | 73 | (* Returns the performances of each program of |progs|. *) 74 | let compare_perfs (progs : prog list) (conf : Config.config) : float list = 75 | let bitslice = 76 | equal_dir 77 | (Utils.get_type_dir List.(hd (hd (hd progs).nodes).p_in).vd_typ) 78 | Bslice 79 | in 80 | let binaries = List.map (compile conf.archi bitslice) progs in 81 | 82 | let perfs = List.map (fun _ -> ref []) progs in 83 | 84 | (* Acquiring the measurements *) 85 | for _ = 1 to repeat do 86 | List.iter2 (fun bin perf -> perf := get_perf bin :: !perf) binaries perfs 87 | done; 88 | 89 | (* Removing extremes *) 90 | (* STDLIB_IMPORT: Sorting a list of float *) 91 | List.iter 92 | (fun perf -> perf := remove_start_end (List.sort Stdlib.compare !perf)) 93 | perfs; 94 | 95 | (* Computing (and returning) averages *) 96 | List.map 97 | (fun perf -> 98 | let len = float_of_int (List.length !perf) in 99 | List.fold_left (fun a b -> a +. b) 0. !perf /. len) 100 | perfs 101 | -------------------------------------------------------------------------------- /src/prelude.ml: -------------------------------------------------------------------------------- 1 | let ( = ) a b = Int.equal a b 2 | let ( <> ) a b = not (Int.equal a b) 3 | let ( < ) (a : int) (b : int) = a < b 4 | let ( > ) (a : int) (b : int) = a > b 5 | let ( <= ) (a : int) (b : int) = a <= b 6 | let ( >= ) (a : int) (b : int) = a >= b 7 | let compare = Int.compare 8 | 9 | module List = struct 10 | include Stdlib.List 11 | 12 | let mem _ _ = 13 | failwith "Use of List.mem is forbidden as it uses the polymorphic `=`" 14 | end 15 | -------------------------------------------------------------------------------- /src/prelude.mli: -------------------------------------------------------------------------------- 1 | (** This module is included in all files to prevent using polymorphic comparators and specific functions from the Stdlib (currently [List.mem]) 2 | 3 | If you {b really} need to use a polymorphic comparator and you know what you're doing, use [Stdlib.] and add a comment starting with [(* STDLIB_IMPORT: ...*)] justifying its use (see, for example, perfs.ml) *) 4 | 5 | (** {1 Utility} *) 6 | 7 | (** Don't allow the polymorphic comparators to be used anywhere in the program *) 8 | 9 | val ( = ) : int -> int -> bool 10 | val ( <> ) : int -> int -> bool 11 | val ( < ) : int -> int -> bool 12 | val ( > ) : int -> int -> bool 13 | val ( <= ) : int -> int -> bool 14 | val ( >= ) : int -> int -> bool 15 | val compare : int -> int -> int 16 | 17 | module List : sig 18 | include module type of Stdlib.List 19 | end 20 | -------------------------------------------------------------------------------- /src/tightprove/parsing/dune: -------------------------------------------------------------------------------- 1 | (ocamllex 2 | (modules lexer_tp)) 3 | 4 | (menhir 5 | (infer true) 6 | (modules parser_tp) 7 | (flags --explain)) 8 | -------------------------------------------------------------------------------- /src/tightprove/parsing/lexer_tp.mll: -------------------------------------------------------------------------------- 1 | { 2 | open Lexing 3 | open Parser_tp 4 | 5 | exception SyntaxError of string 6 | 7 | (* keyword table *) 8 | let kwd_table = Hashtbl.create 10 9 | let _ = 10 | List.iter (fun (a,b) -> Hashtbl.add kwd_table a b) 11 | [ 12 | "rs", TOK_RS; 13 | "in", TOK_IN; 14 | "and", TOK_AND; 15 | "or", TOK_OR; 16 | "xor", TOK_XOR; 17 | "not", TOK_NOT; 18 | "setcst", TOK_SETCST; 19 | "setcstall", TOK_SETCSTALL; 20 | "refresh", TOK_REFRESH; 21 | "ref", TOK_REFRESH; 22 | ] 23 | 24 | let next_line lexbuf = 25 | let pos = lexbuf.lex_curr_p in 26 | lexbuf.lex_curr_p <- 27 | { pos with pos_bol = pos.pos_cnum; (*lexbuf.lex_curr_pos;*) 28 | pos_lnum = pos.pos_lnum + 1 29 | } 30 | } 31 | 32 | 33 | rule token = parse 34 | 35 | | "__END__" { TOK_EOF } 36 | 37 | (* spaces *) 38 | | [' ' '\t']+ { token lexbuf; } 39 | | ['\n'] { next_line lexbuf; token lexbuf; } 40 | | '#' [^ '\n' '\r']* { token lexbuf; } 41 | | "//" [^ '\n' '\r']* { token lexbuf; } 42 | 43 | 44 | (* identifiers / keywords *) 45 | | ['a' - 'z' 'A' - 'Z' '_' ] ['a' - 'z' 'A' - 'Z' '_' '[' ']' '0' - '9']* as id 46 | { try Hashtbl.find kwd_table id with Not_found -> TOK_id id } 47 | 48 | (* symbols *) 49 | | "(" { TOK_LPAREN } 50 | | ")" { TOK_RPAREN } 51 | | "=" { TOK_EQUAL } 52 | | "<<<" { TOK_LROTATE } 53 | | "<<" { TOK_LSHIFT } 54 | | ">>>" { TOK_RROTATE } 55 | | ">>" { TOK_RSHIFT } 56 | 57 | (* integers *) 58 | | ['0'-'9']+ as i { TOK_int (int_of_string i) } 59 | | "0x" ['0'-'9' 'a'-'f' 'A'-'F']+ as i { TOK_int (int_of_string i) } 60 | 61 | (* end of file *) 62 | | eof { TOK_EOF } 63 | 64 | (* error *) 65 | | _ { raise (SyntaxError ("Unexpected char: " ^ Lexing.lexeme lexbuf)) } 66 | -------------------------------------------------------------------------------- /src/tightprove/parsing/parser_api_tp.ml: -------------------------------------------------------------------------------- 1 | open Lexer_tp 2 | open Lexing 3 | open Printf 4 | 5 | let print_position outx lexbuf = 6 | let pos = lexbuf.lex_curr_p in 7 | fprintf outx "%s:%d:%d" pos.pos_fname pos.pos_lnum 8 | (pos.pos_cnum - pos.pos_bol + 1) 9 | 10 | let parse_file (filename : string) : Tp_AST.def = 11 | let f = open_in filename in 12 | let lex = from_channel f in 13 | try 14 | lex.lex_curr_p <- { lex.lex_curr_p with pos_fname = filename }; 15 | Parser_tp.def Lexer_tp.token lex 16 | with 17 | | SyntaxError msg -> 18 | fprintf stderr "%a: %s\n" print_position lex msg; 19 | exit (-1) 20 | | Parser_tp.Error -> 21 | fprintf stderr "%a: syntax error\n" print_position lex; 22 | exit (-1) 23 | 24 | let parse_generic 25 | (parse_fun : (Lexing.lexbuf -> Parser_tp.token) -> Lexing.lexbuf -> 'a) 26 | (str : string) : 'a = 27 | let lex = from_string str in 28 | try parse_fun Lexer_tp.token lex with 29 | | SyntaxError msg -> 30 | fprintf stderr "%a: %s\n" print_position lex msg; 31 | exit (-1) 32 | | Parser_tp.Error -> 33 | fprintf stderr "%a: syntax error\n" print_position lex; 34 | exit (-1) 35 | 36 | let parse_def (str : string) : Tp_AST.def = parse_generic Parser_tp.def str 37 | let parse_expr (str : string) : Tp_AST.expr = parse_generic Parser_tp.expr_a str 38 | -------------------------------------------------------------------------------- /src/tightprove/parsing/parser_tp.mly: -------------------------------------------------------------------------------- 1 | 2 | %{ 3 | open Tp_AST 4 | %} 5 | 6 | /*******************\ 7 | |* tokens *| 8 | \*******************/ 9 | %token TOK_RS 10 | %token TOK_IN 11 | %token TOK_AND 12 | %token TOK_OR 13 | %token TOK_XOR 14 | %token TOK_NOT 15 | %token TOK_SETCST 16 | %token TOK_SETCSTALL 17 | %token TOK_REFRESH 18 | 19 | %token TOK_LPAREN 20 | %token TOK_RPAREN 21 | %token TOK_EQUAL 22 | %token TOK_LROTATE 23 | %token TOK_LSHIFT 24 | %token TOK_RROTATE 25 | %token TOK_RSHIFT 26 | 27 | %token TOK_id 28 | %token TOK_int 29 | 30 | %token TOK_EOF 31 | 32 | 33 | (***************************** Precedence levels ******************************) 34 | 35 | 36 | (******************************** Entry Point *********************************) 37 | %start def 38 | %start expr_a 39 | 40 | %% 41 | 42 | def: 43 | TOK_RS TOK_EQUAL rs=TOK_int 44 | inputs=list(TOK_IN v=TOK_id { v }) 45 | body=list(v=TOK_id TOK_EQUAL e=expr { { lhs = v; rhs = e } }) 46 | TOK_EOF 47 | { { rs = rs; inputs = inputs; body = body } } 48 | 49 | %inline log_op: 50 | | TOK_AND { And } 51 | | TOK_OR { Or } 52 | | TOK_XOR { Xor } 53 | 54 | %inline shift_op: 55 | | TOK_LSHIFT { Lshift } 56 | | TOK_RSHIFT { Rshift } 57 | | TOK_LROTATE { Lrotate } 58 | | TOK_RROTATE { Rrotate } 59 | 60 | expr: 61 | | TOK_LPAREN e=expr TOK_RPAREN { e } 62 | | x=TOK_id { ExpVar x } 63 | | TOK_SETCST TOK_LPAREN i=TOK_int TOK_RPAREN { Const i } 64 | | TOK_SETCSTALL TOK_LPAREN i=TOK_int TOK_RPAREN { ConstAll i } 65 | | TOK_REFRESH x=TOK_id { Refresh(x) } 66 | | TOK_NOT x=TOK_id { Not x } 67 | | op=log_op x=TOK_id y=TOK_id { Log(op,x,y) } 68 | | x=TOK_id op=shift_op i=TOK_int { Shift(op,x,i) } 69 | expr_a: e=expr TOK_EOF { e } 70 | 71 | %% 72 | -------------------------------------------------------------------------------- /src/tightprove/print_tp.ml: -------------------------------------------------------------------------------- 1 | open Tp_AST 2 | open Basic_utils 3 | open Printf 4 | 5 | let log_op_to_str = function And -> "and" | Or -> "or" | Xor -> "xor" 6 | 7 | let shift_op_to_str = function 8 | | Lshift -> "<<" 9 | | Rshift -> ">>" 10 | | Lrotate -> "<<<" 11 | | Rrotate -> ">>>" 12 | 13 | let expr_to_str (e : expr) : string = 14 | match e with 15 | | ExpVar id -> id 16 | | Const c -> sprintf "setcst(0x%x)" c 17 | | ConstAll c -> sprintf "setcstall(0x%x)" c 18 | | BitToReg (id, n) -> sprintf "bit_to_reg(%s,%d)" id n 19 | | Refresh id -> sprintf "refresh %s" id 20 | | Not id -> sprintf "not %s" id 21 | | Log (o, x, y) -> sprintf "%s %s %s" (log_op_to_str o) x y 22 | | Shift (op, e, n) -> sprintf "%s %s %d" e (shift_op_to_str op) n 23 | 24 | let asgn_to_str (asgn : asgn) : string = 25 | sprintf "%s = %s\n" asgn.lhs (expr_to_str asgn.rhs) 26 | 27 | let def_to_str (def : def) : string = 28 | sprintf "rs=%d\n\n%s\n\n%s\n" (* m *) def.rs 29 | (* inputs *) 30 | (join "" (List.map (sprintf "in %s\n") def.inputs)) 31 | (* body *) 32 | (join "" (List.map asgn_to_str def.body)) 33 | 34 | let print_def (def : def) : unit = Printf.printf "%s" (def_to_str def) 35 | 36 | let print_def_to_file (def : def) (filename : string) : unit = 37 | let out = open_out filename in 38 | Printf.fprintf out "%s" (def_to_str def); 39 | flush out 40 | -------------------------------------------------------------------------------- /src/tightprove/tp_AST.ml: -------------------------------------------------------------------------------- 1 | type log_op = And | Or | Xor 2 | type arith_op = Add | Mul | Sub | Div | Mod 3 | type shift_op = Lshift | Rshift | Lrotate | Rrotate 4 | 5 | type expr = 6 | | ExpVar of string 7 | | Const of int 8 | | ConstAll of int 9 | | Refresh of string 10 | | BitToReg of 11 | string * int (* useful for Pyjamask: -1 if string.int == 1; 0 otherwise *) 12 | | Not of string 13 | | Log of log_op * string * string 14 | | Shift of shift_op * string * int 15 | 16 | type asgn = { lhs : string; rhs : expr } 17 | 18 | type def = { 19 | rs : int; (* register size *) 20 | inputs : string list; 21 | body : asgn list; 22 | } 23 | -------------------------------------------------------------------------------- /src/tightprove/tp_IO.ml: -------------------------------------------------------------------------------- 1 | (* Returns two filenames: 2 | - a filename to store the source of |def| 3 | - a filename to store the _refreshed_ version of |def|. 4 | Basically, those files should be used as input and output to 5 | tightprove. 6 | Note that this function creates the directory of the files, but 7 | not the files themselves. (the point being that the caller can 8 | easily create the files should he need to, but doesn't have to 9 | bother create the directory, which would be trickier) 10 | *) 11 | let gen_file_names (def : Tp_AST.def) (conf : Config.config) : string * string = 12 | let hashcode = Hashtbl.hash def in 13 | 14 | let root_dir = conf.tightprove_dir in 15 | let dir = root_dir ^ "/" ^ string_of_int hashcode in 16 | let source_file = dir ^ "/source.tp" in 17 | let refreshed_file = dir ^ "/refreshed.tp" in 18 | 19 | if not (Sys.file_exists conf.tightprove_dir) then 20 | Unix.mkdir conf.tightprove_dir 0o755; 21 | 22 | if not (Sys.file_exists dir) then Unix.mkdir dir 0o755; 23 | 24 | (source_file, refreshed_file) 25 | 26 | (* Search cache for |def| refreshed. 27 | 28 | The cache is fairly approximative for now: each def gets hashed, 29 | and a directory with its hash name is created. Collisions are _not_ 30 | handled, meaning that if 2 defs have the same hash, then they will 31 | erase each other refreshed version each time we try to refresh 32 | them. 33 | 34 | TODO: A better way might be to use SHA256 hash (which we can safely 35 | consider uniq) instead. However, the question "what to hash?" 36 | remains. The answer is probably a textual representation of the 37 | node. To be future-proof though, we need to 1- settle on a 38 | representation, 2- normalize variable names *) 39 | let get_from_cache (def : Tp_AST.def) (conf : Config.config) : Tp_AST.def option 40 | = 41 | let source_file, refreshed_file = gen_file_names def conf in 42 | 43 | if Sys.file_exists source_file && Sys.file_exists refreshed_file then 44 | let source_def = Parser_api_tp.parse_file source_file in 45 | if source_def = def then Some (Parser_api_tp.parse_file refreshed_file) 46 | else None 47 | else None 48 | 49 | (* Runs tightprove on |source_file| to produce |refreshed_file|. 50 | 51 | |register_size| comes from the Tp_AST.def we are refreshing. It is 52 | used to determine whether we are bitslicing or vslicing (if it's 1, 53 | then it's bitslicing, otherwise it's vslicing). *) 54 | let run_tightprove (source_file : string) (refreshed_file : string) 55 | (register_size : int) : unit = 56 | let slicing = if register_size = 1 then "b" else "v" in 57 | 58 | let cmd = 59 | Printf.sprintf "%s %s %s %s %s" Config.sage Config.tightprove source_file 60 | refreshed_file slicing 61 | in 62 | ignore (Unix.system cmd) 63 | 64 | (* Gets a refreshed version of |def|: 65 | - if it's already present in the cache, just fetch it from the cache 66 | - if it's not in the cache, then call tightprove to generate it, 67 | and update the cache *) 68 | let get_refreshed_def (def : Tp_AST.def) (conf : Config.config) : Tp_AST.def = 69 | match get_from_cache def conf with 70 | | Some r_def -> r_def 71 | | None -> 72 | (* Not in the cache, need to send it to tightprove *) 73 | let source_file, refreshed_file = gen_file_names def conf in 74 | (* Generate tightPROVE's input *) 75 | Print_tp.print_def_to_file def source_file; 76 | (* Call tightPROVE *) 77 | run_tightprove source_file refreshed_file def.Tp_AST.rs; 78 | (* Return tightPROVE's output... *) 79 | Parser_api_tp.parse_file refreshed_file 80 | -------------------------------------------------------------------------------- /src/tightprove/usuba_to_tightprove.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | open Tp_AST 4 | 5 | (* true if bitslicing; false if vslicing *) 6 | let bitslice = ref true 7 | 8 | let ident_to_str (id : Usuba_AST.ident) : string = 9 | Str.global_replace (Str.regexp "'") "_" (Ident.name id) 10 | 11 | let arith_to_int (ae : Usuba_AST.arith_expr) : int = Utils.eval_arith_ne ae 12 | 13 | let log_op_to_tp (op : Usuba_AST.log_op) : Tp_AST.log_op = 14 | match op with And -> And | Or -> Or | Xor -> Xor | _ -> assert false 15 | 16 | let shift_op_to_tp (op : Usuba_AST.shift_op) : Tp_AST.shift_op = 17 | match op with 18 | | Lshift -> Lshift 19 | | Rshift -> Rshift 20 | | Lrotate -> Lrotate 21 | | Rrotate -> Rrotate 22 | | RAshift -> 23 | Format.eprintf "Cannot generate arithmetic shifts for tightprove.@."; 24 | assert false 25 | 26 | let rec var_to_tp (v : Usuba_AST.var) : string = 27 | match v with 28 | | Var v -> ident_to_str v 29 | | Index (v, e) -> Format.asprintf "%s[%d]" (var_to_tp v) (arith_to_int e) 30 | | _ -> 31 | Format.eprintf "Invalid var to convert to tp: %a@." 32 | (Usuba_print.pp_var ()) v; 33 | assert false 34 | 35 | (* Warning: shadows above function *) 36 | let var_to_tp (vars_corres : (string, Usuba_AST.var) Hashtbl.t) 37 | (v : Usuba_AST.var) : string = 38 | let tp_var = var_to_tp v in 39 | Hashtbl.add vars_corres tp_var v; 40 | tp_var 41 | 42 | let expr_to_tp (vars_corres : (string, Usuba_AST.var) Hashtbl.t) 43 | (e : Usuba_AST.expr) : Tp_AST.expr = 44 | match e with 45 | | Const (c, _) -> if !bitslice then ConstAll c else Const c 46 | | ExpVar v -> ExpVar (var_to_tp vars_corres v) 47 | | Not (ExpVar v) -> Not (var_to_tp vars_corres v) 48 | | Log (op, ExpVar x, ExpVar y) -> 49 | Log (log_op_to_tp op, var_to_tp vars_corres x, var_to_tp vars_corres y) 50 | | Shift (op, ExpVar e, ae) -> 51 | Shift (shift_op_to_tp op, var_to_tp vars_corres e, arith_to_int ae) 52 | | Fun (f, [ ExpVar v ]) when String.equal (Ident.name f) "refresh" -> 53 | Refresh (var_to_tp vars_corres v) 54 | | e -> 55 | Format.eprintf "expr_to_str: invalid expr `%a`@." (Usuba_print.pp_expr ()) 56 | e; 57 | assert false 58 | 59 | let deq_to_tp (vars_corres : (string, Usuba_AST.var) Hashtbl.t) 60 | (deq : Usuba_AST.deq) : Tp_AST.asgn = 61 | match deq.content with 62 | | Eqn ([ lhs ], e, _) -> 63 | { lhs = var_to_tp vars_corres lhs; rhs = expr_to_tp vars_corres e } 64 | | _ -> assert false 65 | 66 | let rec vd_typ_to_tp (typ : Usuba_AST.typ) (acc : string) : string = 67 | match typ with 68 | | Uint (_, _, 1) -> Format.sprintf "%s" acc 69 | | Uint (_, _, n) -> Format.sprintf "%s[%d]" acc n 70 | | Array (typ', n) -> 71 | vd_typ_to_tp typ' (Format.sprintf "%s[%d]" acc (arith_to_int n)) 72 | | _ -> assert false 73 | 74 | let vd_to_tp (vd : Usuba_AST.var_d) : string = 75 | Format.sprintf "%s%s" (ident_to_str vd.vd_id) (vd_typ_to_tp vd.vd_typ "") 76 | 77 | let get_node_body (def : Usuba_AST.def) : Usuba_AST.deq list = 78 | match def.node with Single (_, body) -> body | _ -> assert false 79 | 80 | let m_as_int = function Mint m -> m | _ -> assert false 81 | 82 | let usuba_to_tp (def : Usuba_AST.def) : 83 | (string, Usuba_AST.var) Hashtbl.t * Tp_AST.def = 84 | assert (Utils.all_vars_same_m def.p_in); 85 | let m = m_as_int (Utils.get_type_m (List.hd def.p_in).vd_typ) in 86 | bitslice := m = 1; 87 | 88 | let vars_corres = Hashtbl.create 10 in 89 | 90 | let tp_def = 91 | { 92 | rs = m; 93 | inputs = List.map vd_to_tp def.p_in; 94 | body = List.map (deq_to_tp vars_corres) (get_node_body def); 95 | } 96 | in 97 | 98 | (vars_corres, tp_def) 99 | -------------------------------------------------------------------------------- /src/verification/bdd_verif.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | open Basic_utils 4 | open Utils 5 | open MLBDD 6 | 7 | (* Abstracting Hashtbl. 8 | This functions should replace the ones in Utils, one day. *) 9 | let print_env env = 10 | ignore (Hashtbl.fold (fun k v _ -> print_endline k.name) env ()) 11 | 12 | let make_env () = Hashtbl.create 100 13 | let env_add env v e = Hashtbl.replace env v e 14 | let env_fetch env v = Hashtbl.find env v 15 | 16 | let rec expr_to_bdd env man (e : expr) = 17 | match e with 18 | | ExpVar (Var v) -> env_fetch env v 19 | | Const 0 -> MLBDD.dfalse man 20 | | Const 1 -> MLBDD.dtrue man 21 | | Not e -> MLBDD.dnot (expr_to_bdd env man e) 22 | | Log (op, e1, e2) -> ( 23 | let e1 = expr_to_bdd env man e1 in 24 | let e2 = expr_to_bdd env man e2 in 25 | match op with 26 | | And -> MLBDD.dand e1 e2 27 | | Or -> MLBDD.dor e1 e2 28 | | Xor -> MLBDD.xor e1 e2 29 | | Andn -> MLBDD.dand (MLBDD.dnot e1) e2) 30 | | _ -> 31 | Printf.printf "Can't convert '%s' to BDD.\n" (Usuba_print.expr_to_str e); 32 | assert false 33 | 34 | let deqs_to_bdd (node1 : def) (deqs1 : deq list) (node2 : def) 35 | (deqs2 : deq list) = 36 | let man = MLBDD.init () in 37 | 38 | let env1 = make_env () in 39 | let env2 = make_env () in 40 | 41 | List.iteri 42 | (fun i ((id, _), _) -> env_add env1 id (MLBDD.ithvar man i)) 43 | node1.p_in; 44 | List.iteri 45 | (fun i ((id, _), _) -> env_add env2 id (MLBDD.ithvar man i)) 46 | node2.p_in; 47 | 48 | let build_bdd deqs env = 49 | List.iter 50 | (fun deq -> 51 | match deq with 52 | | Eqn ([ Var id ], e) -> env_add env id (expr_to_bdd env man e) 53 | | _ -> Printf.printf "Invalid expr: %s\n" (Usuba_print.deq_to_str deq)) 54 | deqs 55 | in 56 | 57 | build_bdd deqs1 env1; 58 | build_bdd deqs2 env2; 59 | 60 | (*let ((id,_),_) = List.nth node1.p_out 3 in 61 | print_endline (MLBDD.to_string (env_fetch env1 id)); 62 | print_endline (join "," (List.map string_of_int (MLBDD.list_of_support (MLBDD.support (env_fetch env1 id)))));*) 63 | (env1, env2) 64 | 65 | let compare_defs (node1 : def) (node2 : def) : bool = 66 | match (node1.node, node2.node) with 67 | | Single (_, body1), Single (_, body2) -> 68 | if node1.p_in <> node2.p_in || node1.p_out <> node2.p_out then 69 | raise (Error "Nodes have different inputs or outputs."); 70 | let env1, env2 = deqs_to_bdd node1 body1 node2 body2 in 71 | print_endline "Verification starts"; 72 | List.for_all 73 | (fun ((id, _), _) -> 74 | let x1 = env_fetch env1 id in 75 | let x2 = env_fetch env2 id in 76 | MLBDD.equal x1 x2) 77 | node1.p_out 78 | | _ -> assert false 79 | 80 | let compare_prog (prog1 : prog) (prog2 : prog) : bool = 81 | compare_defs (last prog1.nodes) (last prog2.nodes) 82 | -------------------------------------------------------------------------------- /src/verification/soundness.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Usuba_AST 3 | open Pass_runner 4 | 5 | exception Unsound of string 6 | 7 | let compare_tables (orig : def) (norm : def) = 8 | let nb_inputs = Utils.p_size norm.p_in in 9 | 10 | let out_size = Utils.p_size orig.p_out in 11 | for i = 0 to Basic_utils.pow 2 out_size - 1 do 12 | let input = Basic_utils.int_to_boollist i nb_inputs in 13 | let out_orig = Interp.Usuba.interp_table orig input in 14 | let out_norm = 15 | Interp.Usuba0.interp_node (Ident.Hashtbl.create 0) norm input 16 | in 17 | (* STDLIB_IMPORT: comparing bool lists *) 18 | if Stdlib.(out_orig <> out_norm) then 19 | raise 20 | (Unsound 21 | (Format.asprintf "%a: %d => expect:%d -- got:%d" (Ident.pp ()) 22 | orig.id i 23 | (Basic_utils.boollist_to_int out_orig) 24 | (Basic_utils.boollist_to_int out_norm))) 25 | done 26 | (* Printf.fprintf stderr "Table %s sound.\n" orig.id.name *) 27 | 28 | let tables_sound (runner : pass_runner) (orig : prog) (normalized : prog) : unit 29 | = 30 | List.iter 31 | (fun x -> 32 | match x.node with 33 | | Table _ -> ( 34 | try 35 | let normed = 36 | List.find 37 | (fun def -> 38 | Basic_utils.contains (Ident.name def.id) (Ident.name x.id)) 39 | normalized.nodes 40 | in 41 | compare_tables x normed 42 | with Not_found -> ()) 43 | | _ -> ()) 44 | (runner#run_module ~conf:Utils.default_conf Expand_multiples.as_pass orig) 45 | .nodes 46 | -------------------------------------------------------------------------------- /subroutines.pl: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use v5.14; 4 | use Getopt::Long; 5 | use FindBin; 6 | 7 | sub samples_location() { 8 | my $ua_dir = $FindBin::Bin; 9 | my $samples = "$ua_dir/../examples/samples"; 10 | GetOptions( 11 | "samples|s=s" => \$samples, # string with default 12 | ) or die "Error in command line arguments"; 13 | if ($samples =~ /.*\/$/) { $samples = substr $samples, 0, length($samples) - 1 }; 14 | say $samples; 15 | return $samples 16 | } 17 | 18 | 1; 19 | -------------------------------------------------------------------------------- /tests/rsc/invalid/typing/test1.ua: -------------------------------------------------------------------------------- 1 | # [Typing error]: types `u16' and `u8' have different word size: 16 vs 8 2 | node f (x:u8, y:u16) returns (z:u8) 3 | let 4 | z = x + y 5 | tel 6 | -------------------------------------------------------------------------------- /tests/rsc/invalid/typing/test2.ua: -------------------------------------------------------------------------------- 1 | # [Typing error]: unbalanced left/right types: 2 | # trying to match [v1,v1,v1,v1,v1,v1,v1]: nothing to match with 3 | node f (x:u8, y:v8) returns (z:u8) 4 | let 5 | z = x + y 6 | tel 7 | -------------------------------------------------------------------------------- /tests/rsc/valid/typing/test.ua: -------------------------------------------------------------------------------- 1 | node f (x:u8,y:u8) returns (z:u8) 2 | let 3 | z = x + y 4 | tel 5 | -------------------------------------------------------------------------------- /tests/test_parsing.ml: -------------------------------------------------------------------------------- 1 | module String_Map = Map.Make (String) 2 | 3 | (* Edit this list if you want to execute usuba on 4 | * different files or with different options *) 5 | 6 | let absolute_dir dir = 7 | if String.starts_with ~prefix:"~" dir then 8 | Filename.concat (Unix.getenv "HOME") 9 | (String.sub dir 2 (String.length dir - 2)) 10 | else if Filename.is_relative dir then Filename.concat (Sys.getcwd ()) dir 11 | else dir 12 | 13 | let examples_dir = ref "~/usuba_benchs/examples/samples/usuba" 14 | 15 | let specs = 16 | Arg.( 17 | align 18 | [ ("--path", Set_string examples_dir, " Path to the .ua files") ]) 19 | 20 | let usage = 21 | Printf.sprintf 22 | "%s [OPTION...] \n\n\ 23 | Test that all files are parsed without errors.\n\n\ 24 | Options:" 25 | Sys.argv.(0) 26 | 27 | let pp_sep ppf () = Format.fprintf ppf " " 28 | 29 | let flush_channel oc = 30 | let rec aux acc = 31 | match input_line oc with 32 | | l -> aux (l :: acc) 33 | | exception End_of_file -> String.concat "\n" (List.rev acc) 34 | in 35 | aux [] 36 | 37 | let () = 38 | Arg.parse specs (fun _ -> ()) usage; 39 | let dir = absolute_dir !examples_dir in 40 | Format.eprintf "Examples dir: %s@." dir; 41 | let files = Sys.readdir dir in 42 | Array.iter 43 | (fun file -> 44 | if Filename.check_suffix file ".ua" then 45 | let file = Filename.concat dir file in 46 | let cmd = Format.asprintf "dune exec -- usuba %s -parse-only" file in 47 | let cmd_out = Unix.open_process_in cmd in 48 | let e = flush_channel cmd_out in 49 | match Unix.close_process_in cmd_out with 50 | | Unix.WEXITED 0 -> () 51 | | _ -> 52 | Format.eprintf "%s@." cmd; 53 | Format.eprintf "Something went wrong: %s@.@." e) 54 | files 55 | -------------------------------------------------------------------------------- /tests/test_parsing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec ocaml unix.cma ./tests/test_parsing.ml "$@" 3 | -------------------------------------------------------------------------------- /usuba-mode.el: -------------------------------------------------------------------------------- 1 | (defvar usuba-mode-hook nil) 2 | 3 | 4 | (defvar usuba-mode-map 5 | (make-keymap) 6 | "Keymap for usuba major mode") 7 | 8 | (add-to-list 'auto-mode-alist '("\\.ua\\'" . usuba-mode)) 9 | 10 | (defconst usuba-font-lock-keywords 11 | (list 12 | '("\\<\\(forall\\|in\\|let\\|node\\|perm\\|returns\\|t\\(?:able\\|el\\)\\|vars\\)\\>" 13 | . font-lock-keyword-face) 14 | '("\\<\\(\\(u\\|v\\|b\\)\\(<[a-zA-Z0-9_']+>\\)?[0-9]+\\(x[0-9]+\\>\\)?\\|bool\\>\\|nat\\>\\)" . font-lock-type-face) 15 | '("\\<[A-Za-z_][A-Za-z0-9_]*\\>" . font-lock-variable-name-face) 16 | '("\\<[0-9]+\\>" . font-lock-constant-face) 17 | '("\\<\\([&|^]=\\|[!&|~^]\\)\\>" . font-lock-builtin-face))) 18 | 19 | (defvar usuba-mode-syntax-table 20 | (let ((st (make-syntax-table))) 21 | (modify-syntax-entry ?_ "w" st) 22 | (modify-syntax-entry ?# "<" st) 23 | (modify-syntax-entry ?\n ">" st) 24 | (modify-syntax-entry ?\/ ". 12" st) 25 | st) 26 | "Syntax table for usuba-mode") 27 | 28 | (defun usuba-prettify-symbols () 29 | (setq prettify-symbols-alist 30 | '( 31 | ("forall" . 8704) ; ∀ 32 | ("in" . 8712) ; ∈ 33 | )) 34 | (global-prettify-symbols-mode t)) 35 | 36 | (defun usuba-mode () 37 | "Major mode for editing Usuba programs" 38 | (interactive) 39 | (kill-all-local-variables) 40 | (set-syntax-table usuba-mode-syntax-table) 41 | (use-local-map usuba-mode-map) 42 | (set (make-local-variable 'font-lock-defaults) '(usuba-font-lock-keywords)) 43 | (setq major-mode 'usuba-mode) 44 | (setq mode-name "usuba") 45 | (usuba-prettify-symbols) 46 | (run-hooks 'usuba-mode-hook)) 47 | 48 | (provide 'usuba-mode) 49 | -------------------------------------------------------------------------------- /usuba.opam: -------------------------------------------------------------------------------- 1 | # This file is generated by dune, edit dune-project instead 2 | opam-version: "2.0" 3 | version: "dev" 4 | synopsis: "Usuba" 5 | description: "TODO" 6 | maintainer: ["Usuba developers"] 7 | authors: ["Usuba developers"] 8 | homepage: "https://usubalang.github.io/usuba/" 9 | doc: "https://usubalang.github.io/usuba/" 10 | bug-reports: "https://github.com/usuba-lang/usuba/issues" 11 | depends: [ 12 | "ocaml" {= "4.14.0"} 13 | "dune" {>= "3.3" & = "3.3.1"} 14 | "sexplib" 15 | "usuba_lib" {= version} 16 | "usuba_pp" {= version} 17 | "odoc" {with-doc} 18 | "ocamlformat" {= "0.23.0"} 19 | ] 20 | build: [ 21 | ["dune" "subst"] {dev} 22 | [ 23 | "dune" 24 | "build" 25 | "-p" 26 | name 27 | "-j" 28 | jobs 29 | "@install" 30 | "@runtest" {with-test} 31 | "@doc" {with-doc} 32 | ] 33 | ] 34 | dev-repo: "git+https://github.com/usuba-lang/usuba.git" 35 | -------------------------------------------------------------------------------- /usuba_lib.opam: -------------------------------------------------------------------------------- 1 | # This file is generated by dune, edit dune-project instead 2 | opam-version: "2.0" 3 | version: "dev" 4 | synopsis: "Usuba Library" 5 | description: "TODO" 6 | maintainer: ["Usuba developers"] 7 | authors: ["Usuba developers"] 8 | homepage: "https://usubalang.github.io/usuba/" 9 | doc: "https://usubalang.github.io/usuba/" 10 | bug-reports: "https://github.com/usuba-lang/usuba/issues" 11 | depends: [ 12 | "ocaml" {= "4.14.0"} 13 | "dune" {>= "3.3" & = "3.3.1"} 14 | "menhir" 15 | "ppx_deriving" 16 | "sexplib" 17 | "ppx_sexp_conv" 18 | "usuba_pp" {= version} 19 | "odoc" {with-doc} 20 | "ocamlformat" {= "0.23.0"} 21 | "alcotest" {with-test} 22 | "ppx_inline_test" {with-test} 23 | ] 24 | build: [ 25 | ["dune" "subst"] {dev} 26 | [ 27 | "dune" 28 | "build" 29 | "-p" 30 | name 31 | "-j" 32 | jobs 33 | "@install" 34 | "@runtest" {with-test} 35 | "@doc" {with-doc} 36 | ] 37 | ] 38 | dev-repo: "git+https://github.com/usuba-lang/usuba.git" 39 | -------------------------------------------------------------------------------- /usuba_pp.opam: -------------------------------------------------------------------------------- 1 | # This file is generated by dune, edit dune-project instead 2 | opam-version: "2.0" 3 | version: "dev" 4 | synopsis: "Usuba PP" 5 | description: "Pretty printing for stdlib modules" 6 | maintainer: ["Usuba developers"] 7 | authors: ["Usuba developers"] 8 | homepage: "https://usubalang.github.io/usuba/" 9 | doc: "https://usubalang.github.io/usuba/" 10 | bug-reports: "https://github.com/usuba-lang/usuba/issues" 11 | depends: [ 12 | "ocaml" {= "4.14.0"} 13 | "dune" {>= "3.3" & = "3.3.1"} 14 | "odoc" {with-doc} 15 | "ocamlformat" {= "0.23.0"} 16 | ] 17 | build: [ 18 | ["dune" "subst"] {dev} 19 | [ 20 | "dune" 21 | "build" 22 | "-p" 23 | name 24 | "-j" 25 | jobs 26 | "@install" 27 | "@runtest" {with-test} 28 | "@doc" {with-doc} 29 | ] 30 | ] 31 | dev-repo: "git+https://github.com/usuba-lang/usuba.git" 32 | --------------------------------------------------------------------------------