Skip to content

Flow 20 --- In-Memory JWE / JWS Quick-start

This scenario runs a 100 % file-less round-trip using two post-quantum algorithms:

  1. Generate an HQC-128 key for encryption/decryption.

  2. Generate an SLH-DSA-SHA2-128S key for signing/verification.

  3. Encrypt a UTF-8 message → Compact JWE (all in RAM).

  4. Decrypt the token back to bytes.

  5. Sign the same bytes → Compact JWS.

  6. Verify the signature, print rich metadata, and confirm the plaintext still matches.

Key points

  • Zero I/O: Every artefact (keys, tokens, plaintext) lives only in memory.

  • Uses modern post-quantum algorithms (HQC-128 & SLH-DSA-128S).

  • Shows the lightweight encrypt() / decrypt() and sign() / verifySignature() helpers that return tokens directly.

  • Ideal as a boiler-plate for micro-services, lambdas, or event pipelines.

When to use it

  • High-throughput services that must avoid disk latency or sandboxed file-system access.

  • Stateless functions (FaaS) or message brokers where tokens flow through headers or payloads.

  • Security demos / smoke tests proving that PQC algorithms work end-to-end without touching the HDD/SSD.

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/ExampleScenario20.java

/* *****************************************************************************
* FILE: ExampleScenario20.java
* Copyright © 2025 Anka Technologies.
* SPDX-License-Identifier: MIT
* ---------------------------------------------------------------------------
* Scenario 20 – 100 % In-Memory PQC Quick-Start
* ---------------------------------------------------------------------------
* Demonstrates how to:
*   * Generate two post-quantum keys (HQC-128 for encryption, SLH-DSA-SHA2-128S
*     for signing) entirely in RAM.
*   * Encrypt UTF-8 data → Compact JWE and decrypt it back to bytes.
*   * Sign the same bytes → Compact JWS and verify the signature.
*   * Inspect end-to-end metadata and validate round-trip integrity.
*
* No temporary files are created; every artefact lives only in memory,
* making this flow ideal for service-to-service integrations and
* event-driven architectures where disk I/O is undesirable.
* ****************************************************************************/
  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.util.List;
import java.util.Objects;
import java.util.Properties;

/**
* <h2>Scenario&nbsp;20 – In-Memory Post-Quantum Crypto (Compact JWE/JWS)</h2>
*
* <p>This scenario performs an <em>entirely file-less</em> encryption ➜ decryption
* and signing ➜ verification cycle with post-quantum algorithms:</p>
* <ol>
*   <li>Generate an HQC-128 key for encryption and decryption.</li>
*   <li>Generate an SLH-DSA-SHA2-128S key for signing and verification.</li>
*   <li>Encrypt a UTF-8 message into a Compact JWE token and decrypt it
*       back to bytes.</li>
*   <li>Sign the same bytes, producing a Compact JWS token, and verify
*       that signature.</li>
* </ol>
*
* <p>All artefacts remain in memory; nothing touches the disk.</p>
*
* @author ANKATech – Security Engineering
  */
  public final class ExampleScenario20 {

  /* Dynamically generated key IDs (avoid clashes between runs) */
  private static final String ENC_KID  = "sc20_HQC128_"      + System.currentTimeMillis();
  private static final String SIGN_KID = "sc20_SLHDSA128S_"  + System.currentTimeMillis();

  /* ====================================================================== */
  /** Entry-point. */
  public static void main(final String[] args) {

       System.out.println("===== SCENARIO 20 START =====");
       System.out.println("""
               Purpose :
                 * 100 % in-memory encrypt ➜ decrypt and sign ➜ verify.
               Steps   :
                 1) Generate HQC-128 key (encrypt/decrypt).
                 2) Generate SLH-DSA-SHA2-128S key (sign/verify).
                 3) Encrypt plaintext -> Compact JWE.
                 4) Decrypt Compact JWE.
                 5) Sign plaintext -> Compact JWS.
                 6) Verify Compact JWS signature.
               --------------------------------------------------------------""");

       try {
           Properties props = ExampleUtil.loadProperties();
           AnkaSecureSdk sdk = ExampleUtil.authenticate(props);

           runScenario(sdk);

       } catch (Exception ex) {
           fatal("Scenario 20 failed", ex);
       }

       System.out.println("===== SCENARIO 20 END =====");
  }

  /* ====================================================================== */
  /** Executes the complete in-memory flow. */
  private static void runScenario(final AnkaSecureSdk sdk) throws AnkaSecureSdkException {

       /* 0 ── plaintext -------------------------------------------------- */
       byte[] plaintext = "Hello PQC world – Scenario 20".getBytes(StandardCharsets.UTF_8);
       System.out.println("[0] Plaintext prepared      (" + plaintext.length + " bytes)");

       /* 1 ── HQC-128 key (encrypt/decrypt) ----------------------------- */
       sdk.generateKey(new GenerateKeySpec()
               .setKid(ENC_KID)
               .setKty("HQC")
               .setAlg("HQC-128")
               .setKeyOps(List.of("encrypt", "decrypt")));
       System.out.println("[1] HQC-128 key generated   -> kid = " + ENC_KID);

       /* 2 ── SLH-DSA-SHA2-128S key (sign/verify) ---------------------- */
       sdk.generateKey(new GenerateKeySpec()
               .setKid(SIGN_KID)
               .setKty("SLH-DSA")
               .setAlg("SLH-DSA-SHA2-128S")
               .setKeyOps(List.of("sign", "verify")));
       System.out.println("[2] SLH-DSA-128S key generated -> kid = " + SIGN_KID);

       /* 3 ── Encrypt (Compact JWE) ------------------------------------ */
       EncryptResult encRes = sdk.encrypt(ENC_KID, plaintext);
       String jwe = encRes.getJweToken();
       System.out.println("[3] JWE created             (length = " + jwe.length() + ")");
       printEncryptMeta(encRes);

       /* 4 ── Decrypt --------------------------------------------------- */
       DecryptResult decRes = sdk.decrypt(jwe);
       byte[] recovered = decRes.getDecryptedData();
       System.out.println("[4] Decrypted text          : " +
               new String(recovered, StandardCharsets.UTF_8));
       printDecryptMeta(decRes);

       /* 5 ── Sign (Compact JWS) --------------------------------------- */
       SignResult sigRes = sdk.sign(SIGN_KID, plaintext);
       String jws = sigRes.getJwsToken();
       System.out.println("[5] JWS created             (length = " + jws.length() + ")");
       printSignMeta(sigRes);

       /* 6 ── Verify ---------------------------------------------------- */
       VerifySignatureResult verRes = sdk.verifySignature(jws);
       System.out.println("[6] Signature valid?        -> " + verRes.isValid());
       printVerifyMeta(verRes);

       /* 7 ── Integrity check ----------------------------------------- */
       boolean match = Objects.equals(
               new String(plaintext, StandardCharsets.UTF_8),
               new String(recovered,  StandardCharsets.UTF_8));
       System.out.println(match
               ? "[✔] SUCCESS – round-trip data matches."
               : "[✘] FAILURE – data mismatch!");
  }

  /* ====================================================================== */
  /* ------------------------- Helper utilities --------------------------- */

  private static void printSignMeta(final SignResult r) {
  System.out.println("----- SIGN METADATA -----");
  System.out.println("Key requested : " + nullSafe(r.getKeyRequested()));
  System.out.println("Key used      : " + nullSafe(r.getActualKeyUsed()));
  System.out.println("Algorithm     : " + nullSafe(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 : " + nullSafe(r.getKeyRequested()));
  System.out.println("Key used      : " + nullSafe(r.getActualKeyUsed()));
  System.out.println("Algorithm     : " + nullSafe(r.getAlgorithmUsed()));
  printWarnings(r.getWarnings());
  }

  private static void printEncryptMeta(final EncryptResult r) {
  System.out.println("----- ENCRYPT METADATA -----");
  System.out.println("Key requested : " + nullSafe(r.getKeyRequested()));
  System.out.println("Key used      : " + nullSafe(r.getActualKeyUsed()));
  System.out.println("Algorithm     : " + nullSafe(r.getAlgorithmUsed()));
  printWarnings(r.getWarnings());
  }

  private static void printDecryptMeta(final DecryptResult r) {
  System.out.println("----- DECRYPT METADATA -----");
  System.out.println("Key requested : " + nullSafe(r.getMeta().getKeyRequested()));
  System.out.println("Key used      : " + nullSafe(r.getMeta().getActualKeyUsed()));
  System.out.println("Algorithm     : " + nullSafe(r.getMeta().getAlgorithmUsed()));
  printWarnings(r.getMeta().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 nullSafe(final String s) {
  return (s == null || s.isBlank()) ? "(none)" : s;
  }

  /** Logs a fatal error and terminates the JVM. */
  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 ExampleScenario20() { /* no-instantiation */ }
  }

How to run

mvn -q compile exec:java\
  -Dexec.mainClass="co.ankatech.ankasecure.sdk.examples.ExampleScenario20"

Console milestones

  • HQC-128 & SLH-DSA-128S keys generated in RAM

  • Compact-JWE produced (string length printed)

  • Decryption returns original UTF-8 text

  • Compact-JWS produced and verified (valid = true)

  • SUCCESS -- decrypted plaintext matches original


Where next?

© 2025 Anka Technologies. All rights reserved.