# Scytl Math Library
Scytl Math Library provides some useful mathematical primitives for projects being developed in Scytl. It also provides native optimization for some important functions from the standard Java library.

## Development

### Java code vs native code
The codebase of Scytl Math contains both Java and native code.

The Java code provides public API to be used in other projects. It also provides pure Java implementation for all API it defines.

The native code only provides optimization for some critical operations like `BigInteger.modPow`. The native code is optional by design, it is not mandatory neither for building dependent projects nor in runtime. If the Java code cannot load the native code via standard JNI mechanism it uses pure Java implementation as a fallback.

It is very important to keep the native code optional. That is why Java and native code are developed in separate modules `scytl-math` and `scytl-math-native`. The first one is an ordinary `jar` module and the second is a `nar` module to be built with `nar-maven-plugin`.     

### How to build
#### Prerequisites
Currently Scytl Math can be build for 64bit Linux and Windows only. The following steps should be performed to prepare the build infrastructure

*   Install Oracle JDK 1.8.
*   Define `JAVA_HOME` environment property pointing to the root of JDK installation.
*   Add `$JAVA_HOME/bin` (`%JAVA_HOME%\bin` on Windows) to `PATH` if necessary.
*   Install Maven 3.2.x. 
*   Add the `bin` subfolder of the Maven installation folder to `PATH`. 
*   **Linux:** Make sure that `gcc` and `make` are fresh and properly installed.
*   **Windows:** Download 64bit MSYS2 from <https://sourceforge.net/projects/msys2/>.
*   **Windows:** Install 64bit MSYS2 into a folder without spaces, for example, `C:\msys64`.
*   **Windows:** Add `C:\msys64\usr\bin` to `PATH`.
*   **Windows:** Open command prompt and install `make` package with command

```
packman -S make
```

*   **Windows:** Download 64bit MinGW from <https://sourceforge.net/projects/mingw-w64/>.
*   **Windows:** Install 64bit MinGW into a folder without space, for example, `C:\mingw-w64`. **Warning! It is very important to choose x86_64 architecture during installation, by default the installer suggests i586.**
*   **Windows:** Add `C:\mingw-64\x86_64-x.x.x-posix-seh-rt_v4-rev0\mingw64\bin` to `PATH`.
*   **Windows:** Check your environment using the commands  
```
bash
java -v
javah -h
gcc -v
make -v
```

#### Default build
The default build is performed using Scytl's Maven repository and standard Maven commands like `mvn clean package` or `mavn clean install`. The native code will be built for the host machine only.

#### Custom build
Custom build is used when the customer wants to use a special build of GMP library. It is possible to perform the build without Scytl's Maven repository but in such a case the following artifact must be copied to local or public Maven repository

*   `com.scytl.gmp:scytl-gmp:x.x.x`
*   `com.github.maven-nar:nar-maven-plugin:3.5.1-scytl`

To perform the custom build use a command of the following from

```
mvn clean package -P custom -Dgmp.include.dir=<folder with gmp.h> -Dgmp.lins.dir==<folder with libgmp.so or libgmp.dll>
```

 The native code will be built for the host machine only.

#### Publishing to Maven repository
To publish Scytl Math in public Maven repository do the follwing

*   Build Scytl Math on a Linux machine.
*   Build Scytl Math on Windows machine.
*   Gather all the artifacts in a single place. If two artifacts have the same name choose the one from from Linux.
*   Publish the artifacts with a single Maven command using `maven-deploy` plugin.  


### Some useful tools
The following tools may be useful:

*   The `tools` folder of the project repository contains the definitions of code style and code format to be imported into IDE.
*   Java system property `-Dcom.scytl.math.jni.debug=true` allows to detect if there are problems with JNI.
*   **Linux:** `nm` and `ldd` commands help to investigate problems with JNI.  
*   **Windows:** `Dependency Walker` (<http://www.dependencywalker.com/>) utility helps to investigate problems with JNI.

## Usage
To use Scytl Math in other projects add to `pom.xml` a dependency like the following

``` xml
<dependency>
    <groupId>com.scytl.math</groupId>
    <artifactId>scytl-math</artifactId>
    <version>${scytl.math.version}</version>
</dependency>
```

## Deployment

### Standalone application
To deploy Scytl Math with a standalone application just make `scytl-math-x.x.x.jar` a part of the application's classpath. If the application requires native optimization then do the following

*   Obtain the corresponding version of GNU MP library. If the generic binary is good enough then download `nar` archive of Scytl GMP Library from Maven repository and extract the required binary. Otherwise download the source from <https://gmplib.org> and build it.
*   Obtain the corresponding native part of Scytl Math. If the generic binary is good enough then download `nar` archive of Scytl Math from Maven repository and extract the required binary. Otherwise download the source from Git repository and perform a custom build against the custom build of GMP as described above.
*   Place the GMP library where the operation system can find and load it.
*   Place the Scytl Math native library `libscytl-math.so` (`scytl-math.dll` on Windows) where Java can find and load it using standard JNI mechanism. Native library from `nar` can have a slightly different name, rename it if necessary or create a symbolic link. Use environment properties `LD_LIBRARY_PATH` or `PATH` or Java system property `-Djava.library.path` to specify where Java can find the Scytl Math native library. 

### Managed application
Normally managed applications should use a Scytl Math instance deployed as a shared library. However if native optimization is not required then it is possible to make `scytl-math-x.x.x.jar` a part of the application's archive. To deploy Scytl Math to the application server treat the application server as a standalone application and apply the procedure described above. 