diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml index 42a9a5a..66d8823 100644 --- a/.github/workflows/java.yml +++ b/.github/workflows/java.yml @@ -33,7 +33,7 @@ jobs: path: liboqs ref: main - name: Build liboqs - run: mkdir build && cd build && cmake .. -G"Ninja" -DBUILD_SHARED_LIBS=ON -DOQS_BUILD_ONLY_LIB=ON && ninja install + run: mkdir build && cd build && cmake .. -G"Ninja" -DOQS_BUILD_ONLY_LIB=ON && ninja install working-directory: liboqs - name: Resolve all maven project dependencies run: mvn dependency:go-offline @@ -62,17 +62,78 @@ jobs: path: liboqs ref: main - name: Install liboqs dependencies - run: env HOMEBREW_NO_AUTO_UPDATE=1 brew install ninja && pip3 install --require-hashes --break-system-packages -r .github/workflows/requirements.txt - working-directory: liboqs + run: | + env HOMEBREW_NO_AUTO_UPDATE=1 brew install ninja openssl@3 + echo "OPENSSL_ROOT_DIR=$(brew --prefix openssl@3)" >> $GITHUB_ENV + export LDFLAGS="-L$(brew --prefix openssl@3)/lib" + echo "LDFLAGS=$LDFLAGS" - name: Build liboqs - run: mkdir build && cd build && cmake .. -G"Ninja" -DBUILD_SHARED_LIBS=ON -DOQS_BUILD_ONLY_LIB=ON && sudo ninja install + run: mkdir build && cd build && cmake .. -G"Ninja" -DOQS_BUILD_ONLY_LIB=ON && sudo ninja install working-directory: liboqs - name: Resolve all maven project dependencies run: mvn dependency:go-offline - name: Build liboqs-java and run tests - run: export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/usr/local/lib" && mvn -P macosx package + run: | + export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/usr/local/lib" + export OPENSSL_PATH=$(brew --prefix openssl@3)/lib + mvn -P macosx "-Dlinker.end.option=/usr/local/lib/liboqs.a -L$OPENSSL_PATH -lcrypto" package - name: Compile KEM, Signatures and Rand examples run: | javac -cp target/liboqs-java.jar examples/KEMExample.java && javac -cp target/liboqs-java.jar examples/SigExample.java && javac -cp target/liboqs-java.jar examples/RandExample.java + + windows: + needs: workflowcheck + runs-on: windows-latest + steps: + - name: Checkout liboqs-java + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4 + + - name: Install MSYS2 + uses: msys2/setup-msys2@v2 + with: + update: true + install: >- + mingw-w64-x86_64-gcc + mingw-w64-x86_64-ninja + mingw-w64-x86_64-cmake + make + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '8' + cache: 'maven' + + - name: Checkout liboqs main + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4 + with: + repository: open-quantum-safe/liboqs + path: liboqs + ref: main + + - name: Build liboqs (static library) + shell: msys2 {0} + run: | + cd liboqs + mkdir build + cd build + cmake .. -G "Ninja" -DOQS_BUILD_ONLY_LIB=ON -DBUILD_SHARED_LIBS=OFF + ninja + + - name: Resolve Maven dependencies + run: mvn dependency:go-offline + + - name: Build liboqs-java and run tests + run: | + $env:Path += ";$env:GITHUB_WORKSPACE\liboqs\build\lib" + $includeDir = "$env:GITHUB_WORKSPACE\liboqs\build\include" + $libDir = "$env:GITHUB_WORKSPACE\liboqs\build\lib" + mvn -Pwindows "-Dliboqs.include.dir=$includeDir" "-Dliboqs.lib.dir=$libDir" package + - name: Compile KEM, Signatures and Rand examples + run: | + javac -cp target\liboqs-java.jar examples\KEMExample.java + javac -cp target\liboqs-java.jar examples\SigExample.java + javac -cp target\liboqs-java.jar examples\RandExample.java diff --git a/README.md b/README.md index eff9af1..d648a20 100644 --- a/README.md +++ b/README.md @@ -67,24 +67,94 @@ To build `liboqs-java` first download or clone this java wrapper into a `liboqs- git clone -b master https://github.com/open-quantum-safe/liboqs-java.git ``` -### Building the OQS dependency +### Windows Build + +#### Prerequisites + +- MinGW-w64 GCC (version 11.5.0 or later) +- CMake +- JDK 1.8 +- Maven 3.8.8 +- Git + +#### Installation Steps + +1. Install MinGW-w64 GCC: +- Download from [WinLibs](https://winlibs.com/#download-release) +- Extract the ZIP file to a directory without spaces +- Add the bin directory to PATH environment variable (e.g., `E:\develop\mingw64\bin`) + - Via Control Panel → System → System Info → Advanced System Settings → Advanced → Environment Variables → PATH + - Or via command line: `setx PATH "E:\develop\mingw64\bin;%PATH%"` (not recommended) + +2. Install CMake: +- Either via winget: `winget install cmake` +- Or download from [cmake.org](https://cmake.org/download/) +- Ensure CMake is added to PATH + +3. Verify installations (by open cmd and type): +```bash +gcc --version +cmake --version +``` + +4. Build liboqs: +```bash +git clone https://github.com/open-quantum-safe/liboqs/ +cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER=gcc -DBUILD_SHARED_LIBS=OFF -S . -B build +cmake --build build -j4 +cd .. +``` -#### Linux/MacOS -First, you must build the `main` branch of [liboqs](https://github.com/open-quantum-safe/liboqs/) according to the liboqs building instructions with shared library support enabled (add `-DBUILD_SHARED_LIBS=ON` to the `cmake` command), followed (optionally) by a `sudo ninja install` to ensure that the compiled library is visible system-wide (by default it installs under `/usr/local/include` and `/usr/local/lib` on Linux/macOS). +5. Install Java dependencies: +- Install JDK 1.8 from [OpenLogic](https://www.openlogic.com/openjdk-downloads) +- Install Maven 3.8.8 from [Maven](https://maven.apache.org/) +- Add both to PATH environment variables +- Verify Java installations: +```bash +java -version +mvn -version +``` +If you clone the liboqs under `liboqs-java` directory, then you can run the following command to build the package: +```bash +mvn package -P windows ``` -git clone -b main https://github.com/open-quantum-safe/liboqs.git -cd liboqs -mkdir build && cd build -cmake -GNinja -DBUILD_SHARED_LIBS=ON .. -ninja -sudo ninja install + +Or else, you should run +```bash +mvn package -P windows -Dliboqs.include.dir="\liboqs\build\include" -Dliboqs.lib.dir="\liboqs\build\lib" +``` + +### Linux/MacOS + +#### Prerequisites +- JDK 1.8 +- GCC +- CMake +- ninja-build +- Maven +- OpenSSL + +#### Build Instructions + +First, you must build the `main` branch of [liboqs](https://github.com/open-quantum-safe/liboqs/) according to the liboqs building instructions with static library, followed (optionally) by a `sudo cmake --install build` to ensure that the compiled library is visible system-wide (by default it installs under `/usr/local/include` and `/usr/local/lib` on Linux/macOS). + +1. Build the liboqs C library to generate liboqs.a +```bash +cd +git clone https://github.com/open-quantum-safe/liboqs/ +cmake -S . -B build +cmake --build build -j4 +#optional +sudo cmake --install build +cd .. ``` +This step will generate the `liboqs/build/liboqs.a` file. ### Building the Java OQS wrapper -To build the `liboqs-java` wrapper type for different operating systems add the `-P ` flag, where ` = {linux, macosx}`. +To build the `liboqs-java` wrapper type for different operating systems add the `-P ` flag, where ` = {linux, macosx, windows}`. For instance, to build `liboqs-java` for MacOS, type: ``` @@ -92,6 +162,11 @@ mvn package -P macosx -Dliboqs.include.dir="/usr/local/include" -Dliboqs.lib.dir ``` The above command will compile the C and Java files and also run the unit tests. +For those who doen't want the `liboqs` library to install system wide. You **have to** change `` to `/liboqs/build/include` to and `` to `/liboqs/build/lib` +``` +mvn package -P macosx -Dliboqs.include.dir="/liboqs/build/include" -Dliboqs.lib.dir="/liboqs/build/lib" +``` + To build without running the default unit tests you can use the `-Dmaven.test.skip=true` command line option as follows: ``` mvn package -P macosx -Dliboqs.include.dir="/usr/local/include" -Dliboqs.lib.dir="/usr/local/lib" -Dmaven.test.skip=true @@ -99,11 +174,10 @@ mvn package -P macosx -Dliboqs.include.dir="/usr/local/include" -Dliboqs.lib.dir The default profile for building is `linux`, so when building on Linux the `-P ` command line option may be omitted. -You may also omit the `-Dliboqs.include.dir` and `-Dliboqs.lib.dir` options in case you installed liboqs in `/usr/local` (true if you ran `sudo ninja install` after building liboqs). +You may also omit the `-Dliboqs.include.dir` and `-Dliboqs.lib.dir` options in case you installed liboqs in `/usr/local` (true if you ran `sudo cmake --install build` after building liboqs). Both the above commands will create a `target` directory with the build files, as well as a `src/main/resources` directory that will contain the `liboqs-jni.so` native library. Finally, a `liboqs-java.jar` will be created inside the `target` directory that will contain all the class files as well as the `liboqs-jni.so` native library. - ### Building and running the examples The examples include: @@ -121,11 +195,19 @@ The examples include: * OpenSSL * System (default) -#### Linux/MacOS - -##### 1) Key Encapsulation example +#### 1) Key Encapsulation example To compile and run the KEM example, type: + +##### Windows + +``` +$ javac -cp target/liboqs-java.jar examples\KEMExample.java +$ java -cp "target\liboqs-java.jar;examples\" KEMExample +``` + +##### Linux/MacOS + ``` javac -cp target/liboqs-java.jar examples/KEMExample.java java -cp target/liboqs-java.jar:examples/ KEMExample @@ -165,7 +247,16 @@ Server shared secret: Shared secrets coincide? true ``` -##### 2) Signatures example +#### 2) Signatures example + +##### Windows + +``` +$ javac -cp target/liboqs-java.jar examples/SigExample.java +$ java -cp "target/liboqs-java.jar;examples\" SigExample +``` + +##### Linux/MacOS ``` javac -cp target/liboqs-java.jar examples/SigExample.java @@ -201,8 +292,16 @@ C0 41 9D 4D A9 B1 5F 4C ... 00 00 00 00 0A 20 2E 41 Valid signature? true ``` -##### 3) Rand example +#### 3) Rand example + +##### Windows + +``` +$ javac -cp target/liboqs-java.jar examples\RandExample.java +$ java -cp "target/liboqs-java.jar;examples\" RandExample +``` +##### Linux/MacOS ``` javac -cp target/liboqs-java.jar examples/RandExample.java java -cp target/liboqs-java.jar:examples/ RandExample diff --git a/examples/KEMExample.java b/examples/KEMExample.java index ca44d33..369ead1 100644 --- a/examples/KEMExample.java +++ b/examples/KEMExample.java @@ -1,6 +1,7 @@ import org.openquantumsafe.*; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; public class KEMExample { @@ -38,6 +39,19 @@ public static void main(String[] args) { byte[] shared_secret_client = client.decap_secret(ciphertext); System.out.println("It took " + (System.currentTimeMillis() - t) + " millisecs to decapsulate the secret."); + byte[] secret_key = client.export_secret_key(); + System.out.println("\nSecret key (Base64):"); + System.out.println(Base64.getEncoder().encodeToString(secret_key)); + + System.out.println("\nShared secrets coincide? " + Arrays.equals(shared_secret_client, shared_secret_server)); + + System.out.println("\nShared secrets (Base64):"); + System.out.println(Base64.getEncoder().encodeToString(shared_secret_server)); + System.out.println("\nPublic key (Base64):"); + System.out.println(Base64.getEncoder().encodeToString(client_public_key)); + System.out.println("\nCiphertext (Base64):"); + System.out.println(Base64.getEncoder().encodeToString(ciphertext)); + client.dispose_KEM(); server.dispose_KEM(); diff --git a/pom.xml b/pom.xml index bad7e78..a6c3143 100644 --- a/pom.xml +++ b/pom.xml @@ -9,16 +9,28 @@ 2.0 liboqs-java: Java wrapper for liboqs liboqs-java offers a Java wrapper providing quantum-resistant cryptographic algorithms via liboqs. - UTF-8 UTF-8 + + + + - + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + org.junit.jupiter junit-jupiter-params @@ -32,7 +44,6 @@ test - macosx @@ -48,6 +59,11 @@ /usr/local/include /usr/local/lib -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin + generic-classic + gcc + + -shared -L${liboqs.lib.dir} + ${liboqs.lib.dir}/liboqs.a -lcrypto @@ -65,10 +81,37 @@ /usr/local/include /usr/local/lib -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux + generic-classic + gcc + + -shared -L${liboqs.lib.dir} + ${liboqs.lib.dir}/liboqs.a -lcrypto + + + + windows + + + platform + windows + + + + oqs-jni + dll + + ${basedir}\liboqs\build\include + ${basedir}\liboqs\build\lib + true + -I"${JAVA_HOME}\include" -I"${JAVA_HOME}\include\win32" + mingw + g++ + + -shared -L${liboqs.lib.dir} -ladvapi32 + ${liboqs.lib.dir}\liboqs.a - @@ -76,7 +119,7 @@ maven-surefire-plugin 2.22.0 - -Xss10M -Djava.library.path=${project.build.outputDirectory} + -Xss10M -Djava.library.path=${basedir}/src/main/resources/ @@ -87,6 +130,23 @@ 1.8 + + maven-antrun-plugin + 3.0.0 + + + initialize + + + + + + + run + + + + org.codehaus.mojo native-maven-plugin @@ -106,8 +166,8 @@ - generic-classic - gcc + ${compiler.provider} + ${compiler.executable} ${java.os.include} -fPIC @@ -116,15 +176,15 @@ -I${liboqs.include.dir} ${project.build.outputDirectory} - gcc + ${linker.executable} - -shared - -L${liboqs.lib.dir} + ${linker.start.option} ${lib_name} ${lib_name_ext} - -loqs + ${linker.end.option} + @@ -139,6 +199,27 @@ + + maven-resources-plugin + 3.1.0 + + + copy-resources + process-classes + + copy-resources + + + ${project.build.outputDirectory} + + + ${basedir}/src/main/resources/ + + + + + + - + \ No newline at end of file