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

/*
 * Copyright 2025 ANKATech Solutions Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
/* *****************************************************************************
 * FILE: ExampleScenario20.java
 * ****************************************************************************/
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;

import static co.ankatech.ankasecure.sdk.examples.ExampleUtil.*;

/**
 * <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
 * @since 2.1.0
 */
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 = loadProperties();
            AnkaSecureSdk sdk = 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!");
    }

    /** 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 ANKATech Solutions INC. All rights reserved.