Cluster Installations of GF2X,NTL, and HElib

The installation of three associated packages on a Linux cluster for fast arithmetic, a number theory library, and homomorphic encryption provides some interesting challenges.

GF2X

GF2X "is a C/C++ software package containing routines for fast arithmetic in GF(2)[x] (multiplication, squaring, GCD) and searching for irreducible/primitive trinomials".

Download and extract into a sensible place, and change to that directory.


mkdir /usr/local/src/GF2X
cd /usr/local/src/GF2X
wget http://gforge.inria.fr/frs/download.php/file/30873/gf2x-1.1.tar.gz
cd gf2x-1.1

Installation for this can take "quite a while". Note the following:

gcc versions 4.3.0 and 4.3.1 have a bug which affects gf2x in a an unpredictable way. It is recommended to upgrade to at least 4.3.2, or
configure with --disable-sse2

Load a later environment module and go through the lengthy make process.


module load gcc/4.9.3
../config
make
make check
make tune-lowlevel
make tune-toom
make tune-fft
make check
make install

The config file simply automates the installation location for future versions.


#!/bin/bash
install=$(basename $(pwd) | sed 's%-%/%')
./configure --prefix=/usr/local/$install

Note that the make tune* steps can "take a while", a technical measurement which you may have seen elsewhere on this 'blog.

Create an environment module and you're done:


mkdir -p /usr/local/Modules/modulefiles/gf2x
cd /user/local/Modules/modulefiles/gf2x
vim -p .desc .version .base

The .desc file will be a one-line description as given above, the .version file is 1.1 for default loads, and the .base takes the following form:


#%Module1.0#####################################################################
##
## $name modulefile
##
set ver [lrange [split [ module-info name ] / ] 1 1 ]
set name [lrange [split [ module-info name ] / ] 0 0 ]
set loading [module-info mode load]
set desc [join [read [ open "/usr/local/Modules/modulefiles/$name/.desc" ] ] ]
proc ModulesHelp { } {
puts stderr "\tThis module sets the environment for $name v$ver"
}
module-whatis "$desc (v$ver)"
if { $loading && ![ is-loaded gcc/4.9.3 ] } {
module load gcc/4.9.3
}
prepend-path --delim " " CPPFLAGS -I/usr/local/$name/$ver/include
prepend-path --delim " " LDFLAGS -L/usr/local/$name/$ver/lib
prepend-path LD_LIBRARY_PATH /usr/local/$name/$ver/lib

As a library it does not invoke any paths to /bin etc. Create a symlink from .base to the installed version, and you're done.


ln -s .base 1.1

NTL

"NTL is a high-performance, portable C++ library providing data structures and algorithms for manipulating signed, arbitrary length integers, and for vectors, matrices, and polynomials over the integers and over finite fields."

Create source directory, download, and extract.


mkdir -p /usr/local/src/NTL
cd /usr/local/src/NTL
wget http://www.shoup.net/ntl/ntl-9.4.0.tar.gz
tar xvf ntl-9.4.0.tar.gz

Load the appropriate environment modules, note that the gf2x is being loaded along with the same version of gcc. "If you want very high-performance for polynomial arithmetic over GF(2), you may want to consider using the gf2x library."


module load gcc/4.9.3
module load gf2x/1.1
cd ntl-9.4.0/src
../../config

The config file looks like the following:


#!/bin/bash
./configure PREFIX=/usr/local/ntl/9.4.0 NTL_GMP_LIP=on NTL_GF2X_LIB=on GMP_PREFIX=/usr/local/gmp/4.3.2/ GF2X_PREFIX=/usr/local/gf2x/1.1

The extra prefix paths are necessary because it doesn't respect environment paths. You have to hardcode them. Nice, eh? Technically that makes the module load commands perhaps less than useful, but it doesn't cost too many keystrokes and no harm is done.

After the configuration run the make.


make
make check
make install

With success, create the various module files and link to the current version.


mkdir -p /usr/local/Modules/modulefiles/ntl
vim -p .base .version .desc
chmod +x .desc
ln -s .base 9.4.0

The .base file will look like the following.


#%Module1.0#####################################################################
##
## $name modulefile
##
set ver [lrange [split [ module-info name ] / ] 1 1 ]
set name [lrange [split [ module-info name ] / ] 0 0 ]
set loading [module-info mode load]
set desc [join [read [ open "/usr/local/Modules/modulefiles/$name/.desc" ] ] ]
proc ModulesHelp { } {
puts stderr "\tThis module sets the environment for $name v$ver"
}
module-whatis "$desc (v$ver)"
if { $loading && ![ is-loaded gcc/4.9.3 ] } {
module load gcc/4.9.3
}
if { $loading && ![ is-loaded gfx2/1.1 ] } {
module load gfx2/1.1
}
prepend-path --delim " " CPPFLAGS -I/usr/local/$name/$ver/include
prepend-path --delim " " LDFLAGS -L/usr/local/$name/$ver/lib
prepend-path LD_LIBRARY_PATH /usr/local/$name/$ver/lib

HElib

HElib is a software library that implements homomorphic encryption (HE).

Again, create a source directory, download and extract. This can use a .zip or a git repository; we'll use the latter.


mkdir -p /usr/local/src/HELIB
cd /usr/local/src/HELIB
git clone https://github.com/shaih/HElib.git
mv HElib HElib201509

Note that it doesn't have version numbers, so check the last change in the git repository. Ugly.

The "build system" for HElib is primitive; no configure script and just a Makefile (with no make install). You'll have to edit the Makefile to have the correct paths etc for the dependencies because, once again, it doesn't respect the environment paths.


cd HElib201509/src
cp Makefile Makefile.ORIG
vim Makefile


# diff Makefile Makefile.ORIG
19c19
< CFLAGS = -g -O2 -I/usr/local/gmp/5.0.2/include -I/usr/local/ntl/9.4.0/include -I/usr/local/gf2x/1.1/include
---
> CFLAGS = -g -O2
54c54
< LDLIBS = -L/usr/local/lib -L/usr/local/gmp/5.0.2/lib -L/usr/local/ntl/9.4.0/lib -L/usr/local/gf2x/1.1/lib -lm
---
> LDLIBS = -L/usr/local/lib -lntl $(GMP) -lm

The Makefile will build the static library fhe.a in the HElib src directory, and then one can build applications programs based on fhe.a, also in the HElib src directory (or set the include and library parameters to include the right things).

Which means the following part is also quite ugly..


mkdir -p /usr/local/helib/201509/lib
cd /usr/local/helib/201509/lib
cp /usr/local/src/HELIB/HElib201509/src/fhe.a .

Create module files as appropriate. Note the short .base file


mkdir -p /usr/local/Modules/modulefiles/helib
cd /usr/local/Modules/modulefiles/helib
vim -p .base .desc .version
ln -s .base 201509
chmod +x .desc


#%Module1.0#####################################################################
##
## $name modulefile
##
set ver [lrange [split [ module-info name ] / ] 1 1 ]
set name [lrange [split [ module-info name ] / ] 0 0 ]
set loading [module-info mode load]
set desc [join [read [ open "/usr/local/Modules/modulefiles/$name/.desc" ] ] ]
proc ModulesHelp { } {
puts stderr "\tThis module sets the envinronment for $name v$ver"
}
module-whatis "$desc (v$ver)"
if { $loading && ![ is-loaded gcc/4.9.3 ] } {
module load gcc/4.9.3
}
if { $loading && ![ is-loaded gfx2/1.1 ] } {
module load gfx2/1.1
}
if { $loading && ![ is-loaded ntl/4.9.0 ] } {
module load ntl/4.9.0
}
prepend-path --delim " " LDFLAGS -L/usr/local/$name/$ver/lib
prepend-path LD_LIBRARY_PATH /usr/local/$name/$ver/lib