Week 11 Update 11.1

During this week I spend most of my time trying to make the Cryptoexperts Poseidon permutation work. Let us recall that the Cryptoexperts instantiation of Poseidon is written in C language. Hence, this required to make a C interface in Rust.

In this update I will present a guideline on how to compile the Cryptoexperts Poseidon permutation and generate a static library in order to use it from Rust. This writing will also serve as a future reference on how to use the C implementation in the Cryptoexperts repository.

  1. Fork or clone the repository. In our poseidon-benchmark repository we added it as a submodule.
  2. In the sources directory run the command make only_c. This action will create 5 files: f251_int128.o, f251.o, poseidon_rc.o, poseidon.o and lib_pos.so.
  3. At this stage you can choose to use the lib_pos.so library but, in Linux, it will require you to set the environmental variable LD_LIBRARY_PATH to a directory containing lib_pos.so or to copy the file to a directory in LD_LIBRARY_PATH. It is easier, however, to generate an static library file that can be used from anywhere in the directory structure. To generate a static library file the following command suffices: ar rcs lib_pos.a poseidon.o poseidon_rc.o f251.o f251_int128.o. It is important to add the prefix lib to the .a file so that the linker recognizes it as a library file. After generating the static library file, we can start creating the Rust interface.
  4. Create a build script build.rs in the root of the repository. In the script, we should tell cargo where to find the library file and its name. It should be something like this:
//build.rs fn main() { println!("cargo:rustc-link-search=src"); println!("cargo:rustc-link-lib=static=_pos"); }
  1. The permutation functions by Cryptoexperts can be found in the poseidon.c file. There are four functions of the Poseidon permutation depending on the input size, namely, void permutation_3(felt_t state[]), void permutation_4(felt_t state[]), void permutation_5(felt_t state[]) and void permutation_9(felt_t state[]), which correspond to arrays each of size 3, 4, 5 and 9, respectively. The type felt_t is a size 4 array of 64 bit unsigned integers, that is, four limbs each of type u64.
  2. In order to make use of any of this functions we need to declare each function usign its signature as shown in the code below.
#[link(name = "_pos", kind = "static")] extern "C" { fn permutation_3(state: *mut c_ulonglong); }

With this setup, when we run cargo it will compile the Rust code and link it with the static library.

In order to fully use the Poseidon permutation I need to add a sponge function to it. I expect to finish that during Week 12. I also hope to finally be able to run the full benchmarks during this week.