Flow 19 --- Runtime Algorithm-Discovery Smoke-Test
This scenario proves that your integration can adapt at runtime by discovering which algorithms are currently RECOMMENDED by the platform and then completing a full sign/verify and encrypt/decrypt round-trip without a single hard-coded algorithm name:
-
Discover the live catalog with
getSupportedAlgorithms()
. -
Pick the first RECOMMENDED sign/verify algorithm and the first RECOMMENDED encrypt/decrypt algorithm that meet strict PQC filters (security level & dual-standard).
-
Generate keys for both algorithms.
-
Compact-JWS sign → verify a sample document.
-
Compact-JWE encrypt → decrypt the same document.
-
Print rich server metadata for every step.
-
Confirm that the decrypted plaintext matches the original.
Key points
Absolutely no brittle constants -- works even if tomorrow's recommended set changes.
Demonstrates
getSupportedAlgorithms()
plus "patch-free" key generation.Covers both PQC signing (level 5) and PQC encryption (level 3).
Drops human-readable artefacts in
temp_files/
for audits and demos.
When to use it
-
Smoke tests & CI gates -- guarantee your code survives future algorithm rotations.
-
Long-lived integrations -- auto-negotiate the most secure option instead of shipping updates.
-
Crypto posture reviews -- show auditors that you honour platform guidance in real time.
Shared helper – this code imports the utility class from
example_util.md (configuration, authentication, JSON).
Complete Java implementation
src/main/java/co/ankatech/ankasecure/sdk/examples/ExampleScenario19.java
/* *****************************************************************************
* FILE: ExampleScenario19.java
* Copyright © 2025 Anka Technologies.
* SPDX-License-Identifier: MIT
* ---------------------------------------------------------------------------
* Scenario 19 – Capability-Discovery Smoke-Test (Post-Quantum Focus)
* ---------------------------------------------------------------------------
* Demonstrates how to:
* * Discover platform-recommended **post-quantum** algorithms that satisfy
* *strict* security-level and standards criteria.
* * Generate keys for each discovered algorithm.
* * Perform non-streaming sign/verify (Compact JWS) and
* encrypt/decrypt (Compact JWE).
* * Validate round-trip integrity and inspect rich metadata.
*
* All transient artifacts are written under <temp_files/>.
* ****************************************************************************/
package co.ankatech.ankasecure.sdk.examples;
import co.ankatech.ankasecure.sdk.AnkaSecureSdk;
import co.ankatech.ankasecure.sdk.exception.AnkaSecureSdkException;
import co.ankatech.ankasecure.sdk.model.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import static co.ankatech.ankasecure.sdk.model.AlgorithmInfo.Category.POST_QUANTUM;
import static co.ankatech.ankasecure.sdk.model.AlgorithmInfo.Status.RECOMMENDED;
/**
* <h2>Scenario 19 – Runtime Discovery of PQC Algorithms</h2>
*
* <p>This scenario discovers two platform-recommended <em>post-quantum</em>
* algorithms at runtime, filtered by <strong>exact</strong> security levels
* and the dual-standards requirement <q>NIST & ENISA</q>:</p>
* <ol>
* <li>Select the first PQC signing algorithm with
* <code>securityLevel 5</code>.</li>
* <li>Select the first PQC encryption algorithm with
* <code>securityLevel 3</code>.</li>
* <li>Generate keys and exercise Compact JWS / Compact JWE helpers.</li>
* <li>Validate round-trip integrity and print verbose metadata.</li>
* </ol>
*
* @author ANKATech – Security Engineering
*/
public final class ExampleScenario19 {
/** Working directory for artifacts. */
private static final Path TEMP_DIR = Path.of("temp_files");
/* ====================================================================== */
/** Entry-point. */
public static void main(final String[] args) {
System.out.println("===== SCENARIO 19 START =====");
System.out.println("""
Purpose :
* Discover PQC signing & encryption algorithms with strict filters.
* Perform compact JWS sign/verify and compact JWE encrypt/decrypt.
--------------------------------------------------------------""");
try {
ensureTempDir(TEMP_DIR);
Properties props = ExampleUtil.loadProperties();
AnkaSecureSdk sdk = ExampleUtil.authenticate(props);
runScenario(sdk);
} catch (Exception ex) {
fatal("Scenario 19 failed", ex);
}
System.out.println("===== SCENARIO 19 END =====");
}
/* ====================================================================== */
/** Executes discovery, key generation, and validation. */
private static void runScenario(final AnkaSecureSdk sdk) throws Exception {
/* 1 – discover algorithms -------------------------------------- */
List<AlgorithmInfo> algorithms = sdk.getSupportedAlgorithms();
AlgorithmInfo signAlg = algorithms.stream()
.filter(a -> a.getStatus() == RECOMMENDED)
.filter(a -> a.getCategory() == POST_QUANTUM)
.filter(a -> Integer.valueOf(5).equals(a.getSecurityLevel()))
.filter(a -> supports(a, "sign", "verify"))
.filter(a -> a.getStandards().containsAll(Set.of("NIST", "ENISA")))
.findFirst()
.orElseThrow(() ->
new IllegalStateException("No PQC signing algorithm level 5 (NIST & ENISA) found."));
AlgorithmInfo encAlg = algorithms.stream()
.filter(a -> a.getStatus() == RECOMMENDED)
.filter(a -> a.getCategory() == POST_QUANTUM)
.filter(a -> Integer.valueOf(3).equals(a.getSecurityLevel()))
.filter(a -> supports(a, "encrypt", "decrypt"))
.filter(a -> a.getStandards().containsAll(Set.of("NIST", "ENISA")))
.findFirst()
.orElseThrow(() ->
new IllegalStateException("No PQC encryption algorithm level 3 (NIST & ENISA) found."));
System.out.println("[1] PQC signing algorithm : " + signAlg.getAlg());
System.out.println("[2] PQC encryption algorithm : " + encAlg.getAlg());
/* prepare sample data ------------------------------------------ */
Path plain = TEMP_DIR.resolve("scenario19_plain.txt");
Files.writeString(
plain,
"Scenario 19 – PQC discovery smoke-test.",
StandardCharsets.UTF_8);
System.out.println("[3] Plaintext prepared -> " + plain.toAbsolutePath());
/* 2 – Compact JWS sign / verify ------------------------------- */
String signKid = "sc19_sign_" + System.currentTimeMillis();
generateKey(sdk, signKid, signAlg);
Path jwsFile = TEMP_DIR.resolve("scenario19.jws");
SignResult signMeta = sdk.signFile(signKid, plain, jwsFile);
System.out.println("[4] JWS created -> " + jwsFile);
printSignMeta(signMeta);
VerifySignatureResult verifyMeta = sdk.verifySignature(jwsFile);
System.out.println("[5] JWS valid? -> " + verifyMeta.isValid());
printVerifyMeta(verifyMeta);
/* 3 – Compact JWE encrypt / decrypt --------------------------- */
String encKid = "sc19_enc_" + System.currentTimeMillis();
generateKey(sdk, encKid, encAlg);
Path jweFile = TEMP_DIR.resolve("scenario19.enc");
EncryptResult encMeta = sdk.encryptFile(encKid, plain, jweFile);
System.out.println("[6] JWE created -> " + jweFile);
printEncryptMeta(encMeta);
Path decFile = TEMP_DIR.resolve("scenario19_dec.txt");
DecryptResultMetadata decMeta = sdk.decryptFile(jweFile, decFile);
System.out.println("[7] Decrypted file -> " + decFile);
printDecryptMeta(decMeta);
/* 4 – round-trip validation ---------------------------------- */
boolean match = Objects.equals(
Files.readString(plain),
Files.readString(decFile));
System.out.println(match
? "[✔] SUCCESS – round-trip data matches."
: "[✘] FAILURE – data mismatch!");
}
/* ====================================================================== */
private static boolean supports(final AlgorithmInfo alg, final String... ops) {
Set<String> caps = alg.getKeyOps().stream()
.map(String::toLowerCase)
.collect(Collectors.toSet());
return List.of(ops).stream()
.map(String::toLowerCase)
.allMatch(caps::contains);
}
private static void generateKey(final AnkaSecureSdk sdk,
final String kid,
final AlgorithmInfo alg) throws AnkaSecureSdkException {
sdk.generateKey(new GenerateKeySpec()
.setKid(kid)
.setKty(alg.getKty())
.setAlg(alg.getAlg())
.setExportable(true));
System.out.printf(" * Key generated -> kid=%s, alg=%s%n", kid, alg.getAlg());
}
/* ====================================================================== */
private static void printSignMeta(final SignResult r) {
System.out.println("----- SIGN METADATA -----");
System.out.println("Key requested : " + ns(r.getKeyRequested()));
System.out.println("Key used : " + ns(r.getActualKeyUsed()));
System.out.println("Algorithm : " + ns(r.getAlgorithmUsed()));
printWarnings(r.getWarnings());
}
private static void printVerifyMeta(final VerifySignatureResult r) {
System.out.println("----- VERIFY METADATA -----");
System.out.println("Valid : " + r.isValid());
System.out.println("Key requested : " + ns(r.getKeyRequested()));
System.out.println("Key used : " + ns(r.getActualKeyUsed()));
System.out.println("Algorithm : " + ns(r.getAlgorithmUsed()));
printWarnings(r.getWarnings());
}
private static void printEncryptMeta(final EncryptResult r) {
System.out.println("----- ENCRYPT METADATA -----");
System.out.println("Key requested : " + ns(r.getKeyRequested()));
System.out.println("Key used : " + ns(r.getActualKeyUsed()));
System.out.println("Algorithm : " + ns(r.getAlgorithmUsed()));
printWarnings(r.getWarnings());
}
private static void printDecryptMeta(final DecryptResultMetadata r) {
System.out.println("----- DECRYPT METADATA -----");
System.out.println("Key requested : " + ns(r.getKeyRequested()));
System.out.println("Key used : " + ns(r.getActualKeyUsed()));
System.out.println("Algorithm : " + ns(r.getAlgorithmUsed()));
printWarnings(r.getWarnings());
}
private static void printWarnings(final List<String> warnings) {
if (warnings != null && !warnings.isEmpty()) {
System.out.println("Warnings :");
warnings.forEach(w -> System.out.println(" * " + w));
}
}
/* ====================================================================== */
private static String ns(final String s) {
return (s == null || s.isBlank()) ? "(none)" : s;
}
private static void ensureTempDir(final Path dir) throws Exception {
if (!Files.exists(dir)) Files.createDirectories(dir);
}
private static void fatal(final String msg, final Throwable t) {
System.err.println(msg);
if (t != null) t.printStackTrace(System.err);
System.exit(1);
}
/** Utility class – no instantiation. */
private ExampleScenario19() { /* no-instantiation */ }
}
How to run
Console milestones
-
Platform-query returns live algorithm list
-
PQC signing algorithm (level 5) selected
-
PQC encryption algorithm (level 3) selected
-
Compact-JWS sign → verify succeeds
-
Compact-JWE encrypt → decrypt succeeds
-
SUCCESS -- decrypted plaintext matches original
Where next?
© 2025 Anka Technologies. All rights reserved.