Skip to content

Flow 33 --- Composite Key Builder API Showcase

This scenario demonstrates 4 API approaches for creating composite keys, from verbose manual construction to simple one-liner factory methods. Shows the evolution of the API and helps developers choose the right construction method for their requirements.

Covers manual construction (full control), builder with manual algorithms (type-safe), builder with auto-selection (recommended), and factory one-liner (simplest). Also showcases client-side validation and advanced lifecycle configuration.

  1. Manual construction - Explicit setters for every parameter (8 lines)
  2. Builder with algorithms - Type-safe builder with explicit algorithm selection (6 lines)
  3. Builder auto-selection - Recommended approach with automatic algorithm selection (4 lines) ✅
  4. Factory one-liner - Simplest approach using pre-configured templates (1 line)

Key points

  • Trade-offs: Control vs simplicity - manual gives full control, factory gives maximum simplicity
  • Builder type-safety: All methods use enums (no string typos), IDE autocomplete, compile-time validation
  • Auto-validation: Builder calls .validate() automatically on .build(), preventing invalid configurations
  • Advanced config: Lifecycle management (usage limits, expiration, soft limits, key operations) available on all methods

When to use it

  • Learning SDK API - Understand all construction approaches before choosing one
  • Choosing API style - Evaluate control vs simplicity trade-offs for your use case
  • Complex lifecycle configs - See advanced configuration with soft limits, expiration warnings
  • Pre-configured templates - Discover factory methods for regulatory compliance (BSI, ANSSI, ETSI)

Shared helper – this code imports the utility class from example_util.md (configuration, authentication).


Complete Java implementation

src/main/java/co/ankatech/ankasecure/sdk/examples/ExampleScenario33.java

/** **************************************************************************
 * FILE: ExampleScenario33.java
 * SCENARIO: Composite Key Builder API Showcase
 * TAGS: composite-keys, builder-pattern, fluent-api, validation
 *************************************************************************** */
package co.ankatech.ankasecure.sdk.examples;

import co.ankatech.ankasecure.sdk.AnkaSecureSdk;
import co.ankatech.ankasecure.sdk.exception.InvalidInputException;
import co.ankatech.ankasecure.sdk.model.*;

import java.time.ZonedDateTime;
import java.util.Arrays;

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

/**
 * <h1>Scenario 33: Composite Key Builder API Showcase</h1>
 * <p>
 * Demonstrates all available methods for creating composite keys, from verbose
 * manual configuration to simple one-liner factory methods. Shows the evolution
 * of the API and best practices.
 * </p>
 *
 * <h3>What You'll Learn:</h3>
 * <ul>
 *   <li>4 different ways to create composite keys (from verbose to simple)</li>
 *   <li>How to use {@link CompositeKeyBuilder} fluent API</li>
 *   <li>How to use {@link RegulatoryTemplateFactory} one-liners</li>
 *   <li>Client-side validation with detailed error messages</li>
 *   <li>Advanced configuration options (usage limits, expiration, exportability)</li>
 * </ul>
 *
 * <h3>API Evolution:</h3>
 * <ol>
 *   <li><strong>Manual Construction:</strong> Full control, verbose (6-10 lines)</li>
 *   <li><strong>Builder with Manual Algorithms:</strong> Type-safe, explicit (5-7 lines)</li>
 *   <li><strong>Builder with Auto-Selection:</strong> Simpler, auto-selects algorithms (3-4 lines)</li>
 *   <li><strong>Factory One-Liner:</strong> Simplest, pre-configured (1 line)</li>
 * </ol>
 *
 *
 * @see CompositeKeyBuilder
 * @see RegulatoryTemplateFactory
 * @see GenerateCompositeKeySpec
 */
public class ExampleScenario33 {

    public static void main(String[] args) {
        try {
            System.out.println("=================================================================");
            System.out.println("  SCENARIO 33: Builder API Showcase");
            System.out.println("=================================================================\n");

            // Initialize SDK
            java.util.Properties props = loadProperties();
            AnkaSecureSdk sdk = authenticate(props);

            // Method 1: Manual construction
            demonstrateManualConstruction(sdk);

            // Method 2: Builder with manual algorithms
            demonstrateBuilderManual(sdk);

            // Method 3: Builder with auto-selection
            demonstrateBuilderAutoSelect(sdk);

            // Method 4: Factory one-liner
            demonstrateFactoryOneLiner(sdk);

            // Advanced: Validation showcase
            demonstrateValidation(sdk);

            // Advanced: Full configuration
            demonstrateAdvancedConfiguration(sdk);

            System.out.println("\n=================================================================");
            System.out.println("  ALL BUILDER PATTERNS DEMONSTRATED SUCCESSFULLY");
            System.out.println("=================================================================");

        } catch (Exception e) {
            fatal("Scenario 33 failed", e);
        }
    }

    /**
     * Method 1: Manual construction (verbose, full control).
     */
    private static void demonstrateManualConstruction(AnkaSecureSdk sdk) throws Exception {
        System.out.println("[1/6] METHOD 1: Manual Construction (Verbose)");
        System.out.println("      Lines of code: 8");
        System.out.println("      Control level: Full\n");

        GenerateCompositeKeySpec spec = new GenerateCompositeKeySpec()
            .setKid("manual_" + System.currentTimeMillis())
            .setMode(GenerateCompositeKeySpec.Mode.HYBRID_KEM_COMBINE)
            .addComponent(ComponentSpec.classical(ClassicalCompositeAlgorithm.X25519))
            .addComponent(ComponentSpec.pqc(PqcCompositeAlgorithm.ML_KEM_768))
            .setKdf(Kdf.HKDF_SHA256)
            .setMaxUsageLimit(1000000)
            .setExportable(false);

        // Manual validation (optional - builder does this automatically)
        CompositeKeyValidator.validate(spec, new ServerAlgorithmResolver(sdk.getSupportedAlgorithms()));

        System.out.println("      Code:");
        System.out.println("      new GenerateCompositeKeySpec()");
        System.out.println("          .setKid(...)");
        System.out.println("          .setMode(Mode.HYBRID_KEM_COMBINE)");
        System.out.println("          .addComponent(ComponentSpec.classical(...))");
        System.out.println("          .addComponent(ComponentSpec.pqc(...))");
        System.out.println("          .setKdf(Kdf.HKDF_SHA256)");

        KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
        System.out.println("      ✅ Manual key generated: " + result.getKid() + "\n");
    }

    /**
     * Method 2: Builder with manual algorithm selection.
     */
    private static void demonstrateBuilderManual(AnkaSecureSdk sdk) throws Exception {
        System.out.println("[2/6] METHOD 2: Builder with Manual Algorithms");
        System.out.println("      Lines of code: 6");
        System.out.println("      Control level: High\n");

        GenerateCompositeKeySpec spec = CompositeKeyBuilder
            .forEncryption("builder_manual_" + System.currentTimeMillis())
            .withAlgorithmCatalog(sdk.getSupportedAlgorithms())
            .withClassical(ClassicalCompositeAlgorithm.RSA_3072)
            .withPqc(PqcCompositeAlgorithm.ML_KEM_768)
            .withKdf(Kdf.HKDF_SHA256)
            .exportable(true)
            .build(); // Auto-validates

        System.out.println("      Code:");
        System.out.println("      CompositeKeyBuilder.forEncryption(kid)");
        System.out.println("          .withClassical(ClassicalCompositeAlgorithm.RSA_3072)");
        System.out.println("          .withPqc(PqcCompositeAlgorithm.ML_KEM_768)");
        System.out.println("          .withKdf(Kdf.HKDF_SHA256)");
        System.out.println("          .build();");

        KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
        System.out.println("      ✅ Builder (manual) key generated: " + result.getKid() + "\n");
    }

    /**
     * Method 3: Builder with auto-selection (recommended).
     */
    private static void demonstrateBuilderAutoSelect(AnkaSecureSdk sdk) throws Exception {
        System.out.println("[3/6] METHOD 3: Builder with Auto-Selection (RECOMMENDED)");
        System.out.println("      Lines of code: 4");
        System.out.println("      Control level: Medium (auto-selects algorithms)\n");

        GenerateCompositeKeySpec spec = CompositeKeyBuilder
            .forEncryption("builder_auto_" + System.currentTimeMillis())
            .withAlgorithmCatalog(sdk.getSupportedAlgorithms())
            .withSecurityLevel(NistSecurityLevel.LEVEL_3)
            .withKdf(Kdf.HKDF_SHA256)
            .build(); // Auto-selects X25519 + ML-KEM-768

        System.out.println("      Code:");
        System.out.println("      CompositeKeyBuilder.forEncryption(kid)");
        System.out.println("          .withSecurityLevel(NistSecurityLevel.LEVEL_3)");
        System.out.println("          .withKdf(Kdf.HKDF_SHA256)");
        System.out.println("          .build();");
        System.out.println("\n      Auto-selected:");
        System.out.println("      - Classical: X25519 (Level 3)");
        System.out.println("      - PQC: ML-KEM-768 (Level 3)");

        KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
        System.out.println("      ✅ Builder (auto) key generated: " + result.getKid() + "\n");
    }

    /**
     * Method 4: Factory one-liner (simplest).
     */
    private static void demonstrateFactoryOneLiner(AnkaSecureSdk sdk) throws Exception {
        System.out.println("[4/6] METHOD 4: Factory One-Liner (SIMPLEST)");
        System.out.println("      Lines of code: 1");
        System.out.println("      Control level: Low (pre-configured)\n");

        // BSI compliance in one line
        GenerateCompositeKeySpec spec = RegulatoryTemplateFactory.bsiHybrid(
            "factory_bsi_" + System.currentTimeMillis(),
            GenerateCompositeKeySpec.Mode.HYBRID_KEM_COMBINE
        );

        System.out.println("      Code:");
        System.out.println("      RegulatoryTemplateFactory.bsiHybrid(kid, Mode.HYBRID_KEM_COMBINE);");
        System.out.println("\n      Pre-configured:");
        System.out.println("      - Mode: HYBRID_KEM_COMBINE");
        System.out.println("      - Classical: X25519 (Level 3)");
        System.out.println("      - PQC: ML-KEM-768 (Level 3)");
        System.out.println("      - KDF: HKDF-SHA256");
        System.out.println("      - Compliance: BSI TR-02102-1 (Germany)");

        KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
        System.out.println("      ✅ Factory key generated: " + result.getKid() + "\n");
    }

    /**
     * Demonstrates client-side validation with detailed error messages.
     */
    private static void demonstrateValidation(AnkaSecureSdk sdk) {
        System.out.println("[5/6] VALIDATION: Fail-Fast Error Detection");
        System.out.println("      Demonstrating client-side validation\n");

        // Test 1: Invalid component count
        try {
            System.out.println("      Test 1: Invalid component count...");
            GenerateCompositeKeySpec invalid = new GenerateCompositeKeySpec()
                .setKid("invalid_count")
                .setMode(GenerateCompositeKeySpec.Mode.HYBRID_KEM_COMBINE)
                .addComponent(ComponentSpec.classical(ClassicalCompositeAlgorithm.X25519))
                // Missing PQC component
                .setKdf(Kdf.HKDF_SHA256);

            CompositeKeyValidator.validate(invalid, new ServerAlgorithmResolver(sdk.getSupportedAlgorithms()));
            System.err.println("      ❌ Should have failed!");

        } catch (InvalidInputException e) {
            System.out.println("      ✅ Caught: " + e.getMessage());
        }

        // Test 2: KDF not applicable for DUALSIGN
        try {
            System.out.println("\n      Test 2: KDF with DUALSIGN (invalid)...");
            GenerateCompositeKeySpec invalid = CompositeKeyBuilder
                .forSignature("invalid_kdf")
                .withAlgorithmCatalog(sdk.getSupportedAlgorithms())
                .withSecurityLevel(NistSecurityLevel.LEVEL_3)
                .withKdf(Kdf.HKDF_SHA256) // Invalid for signatures
                .build();

            System.err.println("      ❌ Should have failed!");

        } catch (InvalidInputException e) {
            System.out.println("      ✅ Caught: " + e.getMessage());
        }

        // Test 3: Algorithm incompatibility
        try {
            System.out.println("\n      Test 3: Algorithm mode incompatibility...");
            GenerateCompositeKeySpec invalid = new GenerateCompositeKeySpec()
                .setKid("invalid_mode")
                .setMode(GenerateCompositeKeySpec.Mode.HYBRID_KEM_COMBINE)
                .addComponent(ComponentSpec.classical(ClassicalCompositeAlgorithm.ED25519)) // Signature alg
                .addComponent(ComponentSpec.pqc(PqcCompositeAlgorithm.ML_KEM_768))          // KEM alg
                .setKdf(Kdf.HKDF_SHA256);

            CompositeKeyValidator.validate(invalid, new ServerAlgorithmResolver(sdk.getSupportedAlgorithms()));
            System.err.println("      ❌ Should have failed!");

        } catch (InvalidInputException e) {
            System.out.println("      ✅ Caught: " + e.getMessage());
        }

        System.out.println("\n      All validation tests passed!\n");
    }

    /**
     * Demonstrates advanced configuration with lifecycle management.
     */
    private static void demonstrateAdvancedConfiguration(AnkaSecureSdk sdk) throws Exception {
        System.out.println("[6/6] ADVANCED: Full Configuration with Lifecycle Management");
        System.out.println("      Demonstrating all optional parameters\n");

        GenerateCompositeKeySpec spec = CompositeKeyBuilder
            .forEncryption("advanced_" + System.currentTimeMillis())
            .withAlgorithmCatalog(sdk.getSupportedAlgorithms())
            .withSecurityLevel(NistSecurityLevel.LEVEL_3)
            .withKdf(Kdf.HKDF_SHA256)
            .maxUsageLimit(1000000)                                              // Hard limit
            .softUsageLimit(800000)                                              // Warning at 80%
            .expiresAt(ZonedDateTime.parse("2030-12-31T23:59:59Z"))             // Hard expiration
            .softLimitExpiration(ZonedDateTime.parse("2030-06-30T23:59:59Z"))   // Warning 6 months early
            .exportable(true)                                                    // Allow public key export
            .withKeyOps(Arrays.asList("encrypt", "decrypt"))                    // Explicit operations
            .build();

        System.out.println("      Configuration:");
        System.out.println("      - Classical: X25519 (Level 3)");
        System.out.println("      - PQC: ML-KEM-768 (Level 3)");
        System.out.println("      - KDF: HKDF-SHA256");
        System.out.println("      - Max Usage: 1,000,000 operations");
        System.out.println("      - Soft Usage: 800,000 (80% warning)");
        System.out.println("      - Hard Expiry: 2030-12-31");
        System.out.println("      - Soft Expiry: 2030-06-30 (6 months warning)");
        System.out.println("      - Exportable: Yes");
        System.out.println("      - Operations: [encrypt, decrypt]");

        KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
        System.out.println("      ✅ Advanced key generated: " + result.getKid());
        System.out.println("      Status: " + result.getStatus());
        System.out.println("      Max Usage: " + result.getMaxUsageLimit());
        System.out.println("      Expires: " + result.getExpiresAt() + "\n");
    }

}

Running the example

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

Expected output

=================================================================
  SCENARIO 33: Builder API Showcase
=================================================================

[1/6] METHOD 1: Manual Construction (Verbose)
      Lines of code: 8
      Control level: Full

      Code:
      new GenerateCompositeKeySpec()
          .setKid(...)
          .setMode(Mode.HYBRID_KEM_COMBINE)
          .addComponent(ComponentSpec.classical(...))
          .addComponent(ComponentSpec.pqc(...))
          .setKdf(Kdf.HKDF_SHA256)
      ✅ Manual key generated: manual_1735435200000

[2/6] METHOD 2: Builder with Manual Algorithms
      Lines of code: 6
      Control level: High

      Code:
      CompositeKeyBuilder.forEncryption(kid)
          .withClassical(ClassicalCompositeAlgorithm.RSA_3072)
          .withPqc(PqcCompositeAlgorithm.ML_KEM_768)
          .withKdf(Kdf.HKDF_SHA256)
          .build();
      ✅ Builder (manual) key generated: builder_manual_1735435200100

[3/6] METHOD 3: Builder with Auto-Selection (RECOMMENDED)
      Lines of code: 4
      Control level: Medium (auto-selects algorithms)

      Code:
      CompositeKeyBuilder.forEncryption(kid)
          .withSecurityLevel(NistSecurityLevel.LEVEL_3)
          .withKdf(Kdf.HKDF_SHA256)
          .build();

      Auto-selected:
      - Classical: X25519 (Level 3)
      - PQC: ML-KEM-768 (Level 3)
      ✅ Builder (auto) key generated: builder_auto_1735435200200

[4/6] METHOD 4: Factory One-Liner (SIMPLEST)
      Lines of code: 1
      Control level: Low (pre-configured)

      Code:
      RegulatoryTemplateFactory.bsiHybrid(kid, Mode.HYBRID_KEM_COMBINE);

      Pre-configured:
      - Mode: HYBRID_KEM_COMBINE
      - Classical: X25519 (Level 3)
      - PQC: ML-KEM-768 (Level 3)
      - KDF: HKDF-SHA256
      - Compliance: BSI TR-02102-1 (Germany)
      ✅ Factory key generated: factory_bsi_1735435200300

[5/6] VALIDATION: Fail-Fast Error Detection
      Demonstrating client-side validation

      Test 1: Invalid component count...
      ✅ Caught: [Error message about missing component]

      Test 2: KDF with DUALSIGN (invalid)...
      ✅ Caught: [Error message about KDF not applicable for signatures]

      Test 3: Algorithm mode incompatibility...
      ✅ Caught: [Error message about Ed25519 being signature algorithm]

      All validation tests passed!

[6/6] ADVANCED: Full Configuration with Lifecycle Management
      Demonstrating all optional parameters

      Configuration:
      - Classical: X25519 (Level 3)
      - PQC: ML-KEM-768 (Level 3)
      - KDF: HKDF-SHA256
      - Max Usage: 1,000,000 operations
      - Soft Usage: 800,000 (80% warning)
      - Hard Expiry: 2030-12-31
      - Soft Expiry: 2030-06-30 (6 months warning)
      - Exportable: Yes
      - Operations: [encrypt, decrypt]
      ✅ Advanced key generated: advanced_1735435200400
      Status: ACTIVE
      Max Usage: 1000000
      Expires: 2030-12-31T23:59:59Z

=================================================================
  ALL BUILDER PATTERNS DEMONSTRATED SUCCESSFULLY
=================================================================

Where next?

© 2025 ANKATech Solutions INC. All rights reserved.