Skip to content

Commit b7e9fd2

Browse files
adding pqc test
1 parent 5f056c4 commit b7e9fd2

5 files changed

Lines changed: 210 additions & 0 deletions

File tree

pqc/java/pqc-test/Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM cgr.dev/chainguard-private/jdk:latest-dev
2+
3+
USER 0
4+
RUN apk add --no-cache maven
5+
USER 65532
6+
7+
WORKDIR /src
8+
9+
# https://downloads.bouncycastle.org/java/docs/PQC-Almanac.pdf
10+
COPY pom.xml .
11+
COPY PQCTest.java src/main/java/PQCTest.java
12+
13+
RUN mvn -B dependency:resolve package -DskipTests
14+
15+
ENTRYPOINT ["java", "-cp", "target/classes:target/dependency/*", "PQCTest"]
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import java.security.KeyPair;
2+
import java.security.KeyPairGenerator;
3+
import java.security.Security;
4+
import java.security.Signature;
5+
6+
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
7+
import org.bouncycastle.jce.provider.BouncyCastleProvider;
8+
import org.bouncycastle.util.Strings;
9+
10+
/**
11+
* Example of ML-DSA signature generation using the ML-DSA-65 parameter set.
12+
*/
13+
public class PQCTest {
14+
private static final byte[] MSG = Strings.toByteArray("Hello, world!");
15+
16+
public static void main(String[] args) throws Exception {
17+
Security.addProvider(new BouncyCastleProvider());
18+
19+
// Generate ML-DSA key pair.
20+
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("MLDSA", "BC");
21+
kpGen.initialize(MLDSAParameterSpec.ml_dsa_65);
22+
KeyPair kp = kpGen.generateKeyPair();
23+
24+
// Create ML-DSA signature object.
25+
Signature mlDsa = Signature.getInstance("MLDSA");
26+
27+
// Create ML-DSA signature.
28+
// Without a SecureRandom, this indicates a deterministic signature.
29+
mlDsa.initSign(kp.getPrivate());
30+
mlDsa.update(MSG);
31+
byte[] signature = mlDsa.sign();
32+
33+
// Verify ML-DSA signature.
34+
mlDsa.initVerify(kp.getPublic());
35+
mlDsa.update(MSG);
36+
37+
if (mlDsa.verify(signature)) {
38+
System.out.println("ML-DSA-65 signature created and verified successfully");
39+
System.exit(0);
40+
}
41+
42+
System.exit(1);
43+
}
44+
}

pqc/java/pqc-test/PQCTest.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import java.security.Provider;
2+
import java.security.Security;
3+
import java.util.Set;
4+
import java.util.TreeSet;
5+
6+
import org.bouncycastle.jce.provider.BouncyCastleProvider;
7+
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
8+
9+
/**
10+
* Lists all PQC algorithms available from Bouncy Castle by querying
11+
* the JCA Security registry after registering both BC providers.
12+
*
13+
* Based on BouncyCastlePQCProvider source:
14+
* https://github.com/bcgit/bc-java/tree/main/prov/src/main/java/org/bouncycastle/pqc
15+
*
16+
*/
17+
public class PQCTest {
18+
19+
public static void main(String[] args) {
20+
Security.addProvider(new BouncyCastlePQCProvider());
21+
22+
Provider bcpqc = Security.getProvider("BCPQC");
23+
24+
System.out.println("=================================================");
25+
System.out.println(" BCPQC Provider Algorithm Listing");
26+
System.out.println("=================================================");
27+
System.out.printf(" Provider : %s%n", bcpqc.getInfo());
28+
System.out.printf(" Version : %.2f%n", bcpqc.getVersion());
29+
System.out.println("-------------------------------------------------");
30+
31+
String[] serviceTypes = { "KeyPairGenerator", "KeyGenerator", "Signature", "KeyFactory", "Cipher", "KeyAgreement" };
32+
33+
Set<String> pqcPrefixes = Set.of(
34+
"ML-KEM", "MLKEM", "ML-DSA", "MLDSA", "SLH-DSA", "SLHDSA"
35+
);
36+
37+
for (String serviceType : serviceTypes) {
38+
Set<String> algs = new TreeSet<>();
39+
for (Provider.Service service : bcpqc.getServices()) {
40+
if (!service.getType().equalsIgnoreCase(serviceType)) continue;
41+
String algUpper = service.getAlgorithm().toUpperCase();
42+
for (String prefix : pqcPrefixes) {
43+
if (algUpper.startsWith(prefix)) {
44+
algs.add(service.getAlgorithm());
45+
break;
46+
}
47+
}
48+
}
49+
if (!algs.isEmpty()) {
50+
System.out.printf("%n [%s]%n", serviceType);
51+
algs.forEach(alg -> System.out.printf(" %s%n", alg));
52+
}
53+
}
54+
55+
System.out.println("\n=================================================");
56+
}
57+
}

pqc/java/pqc-test/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# List BCPQC Provider Algorithm Support
2+
3+
Print the supported [NIST PQC Algorithms](https://csrc.nist.gov/projects/post-quantum-cryptography#pqc-standards) (FIPS 203, FIPS 204, FIPS 205) in the [BouncyCastle BCPQC Provider](https://github.com/bcgit/bc-java/blob/main/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java)
4+
5+
## Basic Usage
6+
7+
```bash
8+
docker build -t pqc:cgr .
9+
docker run pqc:cgr
10+
```
11+
12+
## Alternative Option
13+
14+
Run Example 1 from the (BouncyCastle PQC Almanac)[https://downloads.bouncycastle.org/java/docs/PQC-Almanac.pdf] by overwriting PQCTest.java with PQC-Almanac-Ex1.java
15+
16+
## Example Output
17+
18+
```
19+
=================================================
20+
BCPQC Provider Algorithm Listing
21+
=================================================
22+
Provider : BouncyCastle Post-Quantum Security Provider v1.83
23+
Version : 1.83
24+
-------------------------------------------------
25+
26+
[KeyPairGenerator]
27+
ML-KEM
28+
ML-KEM-1024
29+
ML-KEM-512
30+
ML-KEM-768
31+
32+
[KeyGenerator]
33+
ML-KEM-1024
34+
ML-KEM-512
35+
ML-KEM-768
36+
37+
[KeyFactory]
38+
ML-KEM-1024
39+
ML-KEM-512
40+
ML-KEM-768
41+
42+
[Cipher]
43+
ML-KEM-1024
44+
ML-KEM-512
45+
ML-KEM-768
46+
```

pqc/java/pqc-test/pom.xml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>dev.chainguard</groupId>
8+
<artifactId>pqctest</artifactId>
9+
<version>1.0</version>
10+
<packaging>jar</packaging>
11+
12+
<properties>
13+
<maven.compiler.source>21</maven.compiler.source>
14+
<maven.compiler.target>21</maven.compiler.target>
15+
<bc.version>1.83</bc.version>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.bouncycastle</groupId>
21+
<artifactId>bcprov-jdk18on</artifactId>
22+
<version>${bc.version}</version>
23+
</dependency>
24+
</dependencies>
25+
26+
<build>
27+
<plugins>
28+
<!-- Copy dependencies to target/dependency for easy classpath use -->
29+
<plugin>
30+
<groupId>org.apache.maven.plugins</groupId>
31+
<artifactId>maven-dependency-plugin</artifactId>
32+
<version>3.6.1</version>
33+
<executions>
34+
<execution>
35+
<id>copy-dependencies</id>
36+
<phase>package</phase>
37+
<goals>
38+
<goal>copy-dependencies</goal>
39+
</goals>
40+
<configuration>
41+
<outputDirectory>${project.build.directory}/dependency</outputDirectory>
42+
</configuration>
43+
</execution>
44+
</executions>
45+
</plugin>
46+
</plugins>
47+
</build>
48+
</project>

0 commit comments

Comments
 (0)