Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions examples/provider/CryptoBenchmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.security.spec.ECGenParameterSpec;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.util.*;

import com.wolfssl.provider.jce.WolfCryptProvider;
Expand Down Expand Up @@ -551,6 +553,62 @@ private static void runDHBenchmark(String providerName, int keySize) throws Exce
printKeyGenResults(agreementOps, elapsedTime, agreementOp, providerName, DH_ALGORITHM);
}

/* PBKDF2 benchmark */
private static void runPBKDF2Benchmark(String algorithm, String providerName) throws Exception {
/* Variables for benchmark */
SecretKeyFactory secretKeyFactory;
byte[] salt;
char[] password;
int iterationCount = 10000;
int keyLength = 32;
int processingBytes = 1024;
SecureRandom secureRandom = new SecureRandom();

/* Initialize test parameters */
salt = new byte[16];
secureRandom.nextBytes(salt);
password = "wolfCryptBenchmarkTestPassword".toCharArray();

/* Initialize SecretKeyFactory with specific provider */
try {
secretKeyFactory = SecretKeyFactory.getInstance(algorithm, providerName);
} catch (Exception e) {
System.out.printf(" %-40s Not supported by provider %s%n", algorithm, providerName);
return;
}

/* Create PBEKeySpec */
PBEKeySpec pbeKeySpec = new PBEKeySpec(password, salt, iterationCount, keyLength * 8);

/* Warm up phase */
for (int i = 0; i < WARMUP_ITERATIONS; i++) {
secretKeyFactory.generateSecret(pbeKeySpec);
}

/* Benchmark */
long startTime = System.nanoTime();
int operations = 0;
double elapsedTime = 0;

/* Run for at least 1 second */
do {
secretKeyFactory.generateSecret(pbeKeySpec);
operations++;
elapsedTime = (System.nanoTime() - startTime) / 1_000_000_000.0;
} while (elapsedTime < 1.0);

/* Calculate metrics */
double processedKiB = (operations * processingBytes) / 1024.0;
double throughput = processedKiB / elapsedTime;

String testName = String.format("%s (%s)", algorithm, providerName);
System.out.printf(" %-40s %8.3f KiB took %.3f seconds, %8.3f KiB/s%n",
testName, processedKiB, elapsedTime, throughput);

/* Store result */
results.add(new BenchmarkResult(providerName, algorithm, throughput));
}

public static void main(String[] args) {
try {
/* Check if Bouncy Castle is available */
Expand Down Expand Up @@ -682,6 +740,42 @@ public static void main(String[] args) {
}
}

System.out.println("\n-----------------------------------------------------------------------------");
System.out.println("PBKDF2 Benchmark Results");
System.out.println("-----------------------------------------------------------------------------");

/* List of PBKDF2 algorithms to test */
String[] pbkdf2Algorithms = {
"PBKDF2WithHmacSHA1",
"PBKDF2WithHmacSHA224",
"PBKDF2WithHmacSHA256",
"PBKDF2WithHmacSHA384",
"PBKDF2WithHmacSHA512",
"PBKDF2WithHmacSHA3-224",
"PBKDF2WithHmacSHA3-256",
"PBKDF2WithHmacSHA3-384",
"PBKDF2WithHmacSHA3-512"
};

for (String providerName : providerNames) {
System.out.println("\n" + providerName + ":");

for (String algorithm : pbkdf2Algorithms) {
try {
/* Skip SHA3 algorithms for SunJCE */
if (providerName.equals("SunJCE") && algorithm.contains("SHA3")) {
continue;
}

runPBKDF2Benchmark(algorithm, providerName);
} catch (Exception e) {
/* Print but continue with other algorithms */
System.out.printf(" %-40s Error: %s%n",
algorithm + " (" + providerName + ")", e.getMessage());
}
}
}

System.out.println("-----------------------------------------------------------------------------\n");

/* Print delta table */
Expand Down
90 changes: 55 additions & 35 deletions examples/provider/CryptoBenchmark.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,60 @@
# Flag to track if we downloaded BC during this session
BC_DOWNLOADED=false

# Function to download Bouncy Castle JARs
# Function to get the latest Bouncy Castle version from Maven Central
get_latest_version() {
local metadata_url="https://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk18on/maven-metadata.xml"
if command -v curl >/dev/null; then
curl -s "$metadata_url" | grep '<latest>' | sed -e 's/.*<latest>\(.*\)<\/latest>.*/\1/'
elif command -v wget >/dev/null; then
wget -q -O - "$metadata_url" | grep '<latest>' | sed -e 's/.*<latest>\(.*\)<\/latest>.*/\1/'
else
echo "Error: Neither curl nor wget is installed. Please install one to fetch the latest version."
exit 1
fi
}

# Function to download Bouncy Castle JARs with the latest version
download_bc_jars() {
local bc_version="1.79"
local bc_version=$(get_latest_version)
local lib_dir="../../../lib"
local bc_url="https://downloads.bouncycastle.org/java"
local bc_url="https://repo1.maven.org/maven2/org/bouncycastle"

echo -n "Downloading Bouncy Castle JARs... "
if [ -z "$bc_version" ]; then
echo "failed (could not determine latest version)"
return 1
fi

# Create lib directory if it doesn't exist
mkdir -p "$lib_dir" 2>/dev/null
echo -n "Downloading Bouncy Castle JARs (version $bc_version)... "
mkdir -p "$lib_dir" || {
echo "failed (cannot create $lib_dir)"
return 1
}

# Download both required JARs
if command -v wget >/dev/null; then
wget -q -P "$lib_dir" "$bc_url/bcprov-jdk18on-$bc_version.jar" 2>/dev/null &&
wget -q -P "$lib_dir" "$bc_url/bctls-jdk18on-$bc_version.jar" 2>/dev/null || return 1
wget -P "$lib_dir" "$bc_url/bcprov-jdk18on/$bc_version/bcprov-jdk18on-$bc_version.jar" &&
wget -P "$lib_dir" "$bc_url/bctls-jdk18on/$bc_version/bctls-jdk18on-$bc_version.jar" || {
echo "failed (wget error: check URL or network)"
return 1
}
elif command -v curl >/dev/null; then
curl -s -L -o "$lib_dir/bcprov-jdk18on-$bc_version.jar" "$bc_url/bcprov-jdk18on-$bc_version.jar" 2>/dev/null &&
curl -s -L -o "$lib_dir/bctls-jdk18on-$bc_version.jar" "$bc_url/bctls-jdk18on-$bc_version.jar" 2>/dev/null || return 1
curl -L -o "$lib_dir/bcprov-jdk18on-$bc_version.jar" "$bc_url/bcprov-jdk18on/$bc_version/bcprov-jdk18on-$bc_version.jar" &&
curl -L -o "$lib_dir/bctls-jdk18on-$bc_version.jar" "$bc_url/bctls-jdk18on/$bc_version/bctls-jdk18on-$bc_version.jar" || {
echo "failed (curl error: check URL or network)"
return 1
}
else
echo "failed"
echo "Error: Neither wget nor curl is available. Please install either wget or curl."
echo "failed (neither wget nor curl installed)"
echo "Please install wget or curl."
return 1
fi

# Verify downloads were successful
if [ -f "$lib_dir/bcprov-jdk18on-$bc_version.jar" ] && [ -f "$lib_dir/bctls-jdk18on-$bc_version.jar" ]; then
echo "done"
BC_DOWNLOADED=true
return 0
else
echo "failed"
echo "failed (downloaded files not found)"
return 1
fi
}
Expand All @@ -42,33 +65,32 @@ download_bc_jars() {
cleanup_bc_jars() {
local lib_dir="../../../lib"
echo -n "Removing Bouncy Castle JARs... "
rm -f "$lib_dir/bcprov-jdk18on-1.79.jar" "$lib_dir/bctls-jdk18on-1.79.jar" 2>/dev/null
if [ $? -eq 0 ]; then
echo "done"
return 0
else
echo "failed"
return 1
fi
rm -f "$lib_dir/bcprov-jdk18on-"*".jar" "$lib_dir/bctls-jdk18on-"*".jar" && echo "done" || echo "failed"
}

cd ./examples/build/provider

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../../lib/:/usr/local/lib
cd ./examples/build/provider || {
echo "Error: Cannot change to ./examples/build/provider"
exit 1
}

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../../lib:/usr/local/lib
CLASSPATH="../../../lib/wolfcrypt-jni.jar:."

if [ -f "../../../lib/bcprov-jdk18on-1.79.jar" ] && [ -f "../../../lib/bctls-jdk18on-1.79.jar" ]; then
echo "Running crypto benchmark with Bouncy Castle"
CLASSPATH="$CLASSPATH:../../../lib/bcprov-jdk18on-1.79.jar:../../../lib/bctls-jdk18on-1.79.jar"
# Check for existing Bouncy Castle JARs (any version)
if ls "../../../lib/bcprov-jdk18on-"*".jar" "../../../lib/bctls-jdk18on-"*".jar" 2>/dev/null; then
latest_bc_jar=$(ls -t "../../../lib/bcprov-jdk18on-"*".jar" | head -n 1)
bc_version=$(basename "$latest_bc_jar" | sed -e 's/bcprov-jdk18on-//' -e 's/.jar$//')
echo "Running crypto benchmark with Bouncy Castle (version $bc_version)"
CLASSPATH="$CLASSPATH:$latest_bc_jar:../../../lib/bctls-jdk18on-$bc_version.jar"
else
echo "Bouncy Castle JARs not found in lib directory"
read -p "Would you like to download Bouncy Castle JARs? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
if download_bc_jars; then
echo "Running crypto benchmark with Bouncy Castle"
CLASSPATH="$CLASSPATH:../../../lib/bcprov-jdk18on-1.79.jar:../../../lib/bctls-jdk18on-1.79.jar"
bc_version=$(get_latest_version)
echo "Running crypto benchmark with Bouncy Castle (version $bc_version)"
CLASSPATH="$CLASSPATH:../../../lib/bcprov-jdk18on-$bc_version.jar:../../../lib/bctls-jdk18on-$bc_version.jar"
else
echo "Running crypto benchmark without Bouncy Castle due to download failure"
fi
Expand All @@ -77,11 +99,9 @@ else
fi
fi

# Run the benchmark
java -classpath $CLASSPATH -Dsun.boot.library.path=../../../lib/ CryptoBenchmark $@
java -XX:-TieredCompilation -XX:ReservedCodeCacheSize=1024m -classpath "$CLASSPATH" -Dsun.boot.library.path=../../../lib/ CryptoBenchmark "$@"

# Always prompt for cleanup after benchmark completion if Bouncy Castle files exist
if [ -f "../../../lib/bcprov-jdk18on-1.79.jar" ] && [ -f "../../../lib/bctls-jdk18on-1.79.jar" ]; then
if ls "../../../lib/bcprov-jdk18on-"*".jar" "../../../lib/bctls-jdk18on-"*".jar" 2>/dev/null; then
echo
read -p "Would you like to remove the Bouncy Castle JARs? (y/n) " -n 1 -r
echo
Expand Down