Skip to content

Commit

Permalink
Merge squash commit
Browse files Browse the repository at this point in the history
  • Loading branch information
geovandro committed May 1, 2023
1 parent 240909f commit 91152b9
Show file tree
Hide file tree
Showing 19 changed files with 504 additions and 195 deletions.
95 changes: 95 additions & 0 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Android CI

on:
push:
branches: [ "master", "dev" ]
paths-ignore:
- '**/README.md'
pull_request:
branches: [ "master" ]
paths-ignore:
- '**/README.md'

jobs:
instrumentation-tests:
name: Instrumentation tests
runs-on: macos-latest
strategy:
fail-fast: true
matrix:
api-level: [24]
target: [default]
arch: [x86_64]
abi: [x86, x86_64]
include:
- api-level: 30
target: google_apis
arch: x86_64
abi: armeabi-v7a
- api-level: 30
target: google_apis
arch: x86_64
abi: arm64-v8a
steps:
- name: checkout
uses: actions/checkout@v3

- uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'

# # If you have an existing workflow invoking Gradle, you can add an initial "Setup Gradle" Step to benefit from caching,
# # build-scan capture and other features. All subsequent Gradle invocations will benefit from
# # this initial setup, via init scripts added to the Gradle User Home.
# # See https://github.com/ReactiveCircus/android-emulator-runner/issues/229 for improving performance
# # see https://github.com/gradle/gradle-build-action
- name: Setup and build with Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: |
:liboqs-android:clean
:liboqs-android:assembleDebugAndroidTest
# github action for storing relevant files for future restore (defined via 'path').
# It can store up to 10GB per repo, where github starts evicting old caches.
# see https://github.com/actions/cache
- name: AVD cache
uses: actions/cache@v3
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
/Users/runner/gradle-installations/*
key: avd-${{ matrix.api-level }}-${{ matrix.target }}-${{ matrix.arch }}

- name: create AVD and generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: ${{ matrix.arch }}
emulator-boot-timeout: 600
avd-name: test
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: false
script: echo "Generated AVD snapshot for caching."

- name: run tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: ${{ matrix.arch }}
profile: pixel_2
avd-name: test
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: |
./gradlew :liboqs-android:installDebugAndroidTest -Pabi-splits=${{ matrix.abi }}
adb shell am instrument -w --abi ${{ matrix.abi }} -e debug false -e package com.example.android com.example.android.test/androidx.test.runner.AndroidJUnitRunner
#./gradlew :liboqs-android:connectedDebugAndroidTest
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
.DS_Store
/build
/captures
/outputs
.externalNativeBuild
.cxx
local.properties
43 changes: 23 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
![Project workflow](https://github.com/geovandro/PQCryptoOnAndroid/actions/workflows/android.yml/badge.svg)

# PQCryptoOnAndroid

PQCryptoOnAndroid provides a sample Android project with [instrumentation tests](https://developer.android.com/reference/android/app/Instrumentation) for the NIST PQC KEM and Signature algorithms.

The PQC algorithm implementations come from the [libOQS](https://github.com/open-quantum-safe/liboqs) library.
The project illustrates how to deploy PQCrypto instrumented testing on multiple Android cpu architectures and OS versions (APIs).
The PQC implementations come from the [libOQS](https://github.com/open-quantum-safe/liboqs) library.
The project illustrates how to deploy PQCrypto instrumented testing on multiple Android CPU architectures and OS versions (APIs). It also allows to run the tests via Github CI actions.

PQCryptoOnAndroid is a fork of [LibOQSTestApp](https://github.com/Hatzen/LibOQSTestApp) and addresses multiple issues, including:
* Builds libOQS on 32-bit ARMv7 and x86 (in addition to ARMv8 and x86_64) architectures.
* Fixes a stack overflow issue of Classic McEliece. McEliece needs a 2-4MB stack but the Android JVM (ART) threads are defaulted to 1MB stacks.
* Allows to locally run PQCrypto tests on emulator devices for all major Android ABIs (armeabi-v7a, arm64-v8a, x86 and x86_64) without long boot timings (in certain [hardware](https://developer.android.com/studio/run/emulator-acceleration#vm-windows)).
PQCryptoOnAndroid is a fork of [LibOQSTestApp](https://github.com/Hatzen/LibOQSTestApp) and addresses issues like:
* Building and testing (via Github CI on remote emulators) libOQS on 32-bit ARMv7 and x86 (in addition to ARMv8 and x86_64) architectures.
* Stack overflow from Classic McEliece. McEliece requires 2-4MB stack space while the Android JVM (ART) thread stack size is 1MB by default. PQCryptoOnAndroid increases the thread stack size in those cases to allow Classic McEliece tests to run.
* Slow testing on emulators. Allows to locally run PQC tests on emulator devices for major Android ABIs (armeabi-v7a, arm64-v8a, x86 and x86_64) without long boot timings (in certain [hardware](https://developer.android.com/studio/run/emulator-acceleration#vm-windows)).
  This project gives tailored emulator configurations for faster local tests.

## Project structure

Expand All @@ -25,30 +28,30 @@ The project is split into
A Prebuilt version of libOQS (commit [b1d42d6](https://github.com/open-quantum-safe/liboqs/commit/b1d42d61f63aa61ce007ada7939e326e0d6e896c)) is provided for all Android ABIs (see `liboqs-android/jni/jniLibs/*`).
You can also generate updated prebuilt `liboqs.so` files for the latest libOQS versions by running the `gen_prebuilt_liboqs.sh` script (require NDK installed).

The jni files `app/jni/jni/*` are slightly modified (from the [libOQS java wrapper](https://github.com/open-quantum-safe/liboqs-java)) (package name changes and a minor fix) to compile successfully.
The jni files `app/jni/jni/*` are slightly modified (from the [libOQS java wrapper](https://github.com/open-quantum-safe/liboqs-java)) (such as the McEliece thread fix) to compile and run successfully.

## Building and testing the project on Windows (should work on Ubuntu w/ small changes)
## Building and testing the project (tested on Windows but should work on Ubuntu and MacOS w/ small changes)
- Make sure you have a Java JDK installed.
- Download and install [Android Studio](https://developer.android.com/studio).
- Import the cloned PQCryptoOnAndroid project into Android Studio: `File` -> `New` -> `Import Project`.
- Build: `Build` -> `Make Project`.
- Sync the Gradle configurations: `File` -> `Sync Project with Gradle Files`.
- Create an AVD device (emulator):
- `Tools` -> `Device Manager`. `Create Device`.
- `Tablet`: `Nexus 10` -> `Next`. Now select an Android image:
* For x86 ABI you could pick under `recommended` an image with `API 24 : ABI x86`.
* For x86_64 ABI you could pick under `x86 images` an image with `API 24 : ABI x86_64`.
* For armeabi-v7a or arm64-v8 ABIs:
* On an ARM host: you could pick under `other images` an image with `API 24 : ABI armeabi-v7a or ABI arm64-v8a`.
* On a x86_64 host: pick under `x86 images` an image with `API 30 : ABI x86_64`. see [Run ARM binaries on Android emulator](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html).
* For armeabi-v7a or arm64-v8a ABIs:
* On an ARM-based host, pick under `other images` an image with ABI `armeabi-v7a` or `arm64-v8a`. Recommended an API level between 24 and 31.
* On a x86_64 host: pick under `x86 images` an image with `API 30 : ABI x86_64` (see also [Run ARM binaries on Android emulator](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html)).
- `Next` -> `Finish`.
- Run the instrumented tests on the emulator.
- Start the emulator: `"play button"`. If booting time is slow check out [hardware accelation for emulators](https://developer.android.com/studio/run/emulator-acceleration#vm-windows).
- Open Android studio terminal (`View` -> `Tool Windows` -> `Terminal`).
- Type: `./gradlew connectedDebugAndroidTest -i`.

The instrumented tests should run and the result can be viewed by opening the xml report file under `.\liboqs-android\build\outputs\androidTest-results\connected\` .
See a successful sample [report](https://github.com/geovandro/PQCryptoOnAndroid/tree/master/liboqs-android/sample-test-report/report.xml).

- Build the project for instrumentation tests locally on the emulator:
- Open Android studio terminal (`View` -> `Tool Windows` -> `Terminal`).
- Run: `.\gradlew :liboqs-android:assembleDebugAndroidTest [-Pabi-splits=<ABI>]`
- Run the instrumented tests on the emulator:
- Start the emulator: `"play button"`. If booting time is slow check out [hardware accelation for emulators](https://developer.android.com/studio/run/emulator-acceleration#vm-windows).
- Open Android studio terminal (`View` -> `Tool Windows` -> `Terminal`).
- Run: `.\gradle :liboqs-android:connectedDebugAndroidTest -i [-Pabi-splits=<ABI>]`.
&emsp;&emsp;&ensp;The optional parameter `-Pabi-splits=<ABI>` allows you to install a specific ABI into the APK. This is needed for testing ARM ABIs on x86_64 emulators. If a specific ABI is not set, multiple versions are shipped and the emulator will pick an x86-based one as its primary ABI. See [Android platform ABI support](https://developer.android.com/ndk/guides/abis#android-platform-abi-support).

## TODOs
- [ ] Add tests for an Android device running a post-quantum OpenSSL client to connect to a remote TLS server.
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
}

android {
namespace "com.example.pqcryptoonandroid"
compileSdkVersion 31
//ndkVersion '21.2.6472646'

Expand Down
3 changes: 1 addition & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.pqcryptoonandroid">

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
Expand Down
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.


buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.2'
classpath 'com.android.tools.build:gradle:8.1.0-alpha11'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
11 changes: 7 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 --add-opens java.base/java.io=ALL-UNNAMED
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
#--add-opens java.base/java.io=ALL-UNNAMED
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
#org.gradle.java.home=C\:\\Program Files\\Java\\jdk-11
#android.enableJetifier=true # it makes building slower, so if you don't have libraries that don't support androix natively, disable it.
#org.gradle.java.home=C\:\\Program Files\\Java\\jdk-17
org.gradle.daemon=true
org.gradle.caching=true
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Wed Mar 31 21:18:33 CEST 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.2-bin.zip
Loading

0 comments on commit 91152b9

Please sign in to comment.