This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git

commit 3040518338ba71a5714ad7cb752e0e40d0a28f89
Author: Jiri Ondrusek <[email protected]>
AuthorDate: Thu Mar 26 15:44:26 2026 +0100

    Pqc native support
---
 docs/modules/ROOT/examples/components/pqc.yml      |   6 +-
 docs/modules/ROOT/examples/dataformats/pqc.yml     |   6 +-
 .../ROOT/pages/reference/extensions/pqc.adoc       |  14 +-
 extensions-jvm/pom.xml                             |   1 -
 .../component/pqc/deployment/PqcProcessor.java     |  46 -----
 .../BouncyCastleAdditionalProviderBuildItem.java   |  26 +--
 .../deployment/BouncyCastleSupportProcessor.java   |  14 +-
 .../support/bouncycastle/BouncyCastleRecorder.java |  43 +++--
 extensions/pom.xml                                 |   1 +
 .../pqc/deployment/pom.xml                         |   4 +
 .../component/pqc/deployment/PqcProcessor.java     |  81 +++++++++
 {extensions-jvm => extensions}/pqc/pom.xml         |   2 +-
 {extensions-jvm => extensions}/pqc/runtime/pom.xml |   5 +
 .../main/resources/META-INF/quarkus-extension.yaml |   1 -
 integration-tests-jvm/pom.xml                      |   1 -
 .../quarkus/component/pqc/it/PqcResource.java      |  50 ------
 integration-tests/pom.xml                          |   1 +
 .../pqc/pom.xml                                    |  36 ++++
 .../quarkus/component/pqc/it/PqcProducers.java     |  89 ++++++++++
 .../quarkus/component/pqc/it/PqcResource.java      | 187 +++++++++++++++++++++
 .../camel/quarkus/component/pqc/it/PqcIT.java      |  17 +-
 .../camel/quarkus/component/pqc/it/PqcTest.java    | 159 ++++++++++++++++++
 tooling/scripts/test-categories.yaml               |   1 +
 23 files changed, 636 insertions(+), 155 deletions(-)

diff --git a/docs/modules/ROOT/examples/components/pqc.yml 
b/docs/modules/ROOT/examples/components/pqc.yml
index 5d107de78c..723e0663d8 100644
--- a/docs/modules/ROOT/examples/components/pqc.yml
+++ b/docs/modules/ROOT/examples/components/pqc.yml
@@ -2,11 +2,11 @@
 # This file was generated by 
camel-quarkus-maven-plugin:update-extension-doc-page
 cqArtifactId: camel-quarkus-pqc
 cqArtifactIdBase: pqc
-cqNativeSupported: false
-cqStatus: Preview
+cqNativeSupported: true
+cqStatus: Stable
 cqDeprecated: false
 cqJvmSince: 3.24.0
-cqNativeSince: n/a
+cqNativeSince: 3.35.0
 cqCamelPartName: pqc
 cqCamelPartTitle: PQC Algorithms
 cqCamelPartDescription: Post Quantum Cryptography Signature and Verification 
component.
diff --git a/docs/modules/ROOT/examples/dataformats/pqc.yml 
b/docs/modules/ROOT/examples/dataformats/pqc.yml
index 57e5f19113..62643f1ab3 100644
--- a/docs/modules/ROOT/examples/dataformats/pqc.yml
+++ b/docs/modules/ROOT/examples/dataformats/pqc.yml
@@ -2,11 +2,11 @@
 # This file was generated by 
camel-quarkus-maven-plugin:update-extension-doc-page
 cqArtifactId: camel-quarkus-pqc
 cqArtifactIdBase: pqc
-cqNativeSupported: false
-cqStatus: Preview
+cqNativeSupported: true
+cqStatus: Stable
 cqDeprecated: false
 cqJvmSince: 3.24.0
-cqNativeSince: n/a
+cqNativeSince: 3.35.0
 cqCamelPartName: pqc
 cqCamelPartTitle: PQC (Post-Quantum Cryptography)
 cqCamelPartDescription: Encrypt and decrypt messages using Post-Quantum 
Cryptography Key Encapsulation Mechanisms (KEM).
diff --git a/docs/modules/ROOT/pages/reference/extensions/pqc.adoc 
b/docs/modules/ROOT/pages/reference/extensions/pqc.adoc
index 2e95efcd0c..1c17849e83 100644
--- a/docs/modules/ROOT/pages/reference/extensions/pqc.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/pqc.adoc
@@ -4,17 +4,17 @@
 = PQC Algorithms
 :linkattrs:
 :cq-artifact-id: camel-quarkus-pqc
-:cq-native-supported: false
-:cq-status: Preview
-:cq-status-deprecation: Preview
+:cq-native-supported: true
+:cq-status: Stable
+:cq-status-deprecation: Stable
 :cq-description: Post Quantum Computing Signature and Verification component.
 :cq-deprecated: false
 :cq-jvm-since: 3.24.0
-:cq-native-since: n/a
+:cq-native-since: 3.35.0
 
 ifeval::[{doc-show-badges} == true]
 [.badges]
-[.badge-key]##JVM since##[.badge-supported]##3.24.0## 
[.badge-key]##Native##[.badge-unsupported]##unsupported##
+[.badge-key]##JVM since##[.badge-supported]##3.24.0## [.badge-key]##Native 
since##[.badge-supported]##3.35.0##
 endif::[]
 
 Post Quantum Computing Signature and Verification component.
@@ -30,6 +30,10 @@ Please refer to the above links for usage and configuration 
details.
 [id="extensions-pqc-maven-coordinates"]
 == Maven coordinates
 
+https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-pqc[Create
 a new project with this extension on {link-quarkus-code-generator}, 
window="_blank"]
+
+Or add the coordinates to your existing project:
+
 [source,xml]
 ----
 <dependency>
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index 7a000433fb..0251dc69e6 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -80,7 +80,6 @@
         <module>lucene</module>
         <module>mvel</module>
         <module>opensearch</module>
-        <module>pqc</module>
         <module>printer</module>
         <module>pulsar</module>
         <module>python</module>
diff --git 
a/extensions-jvm/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java
 
b/extensions-jvm/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java
deleted file mode 100644
index b4826f3f13..0000000000
--- 
a/extensions-jvm/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-package org.apache.camel.quarkus.component.pqc.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
-import org.jboss.logging.Logger;
-
-class PqcProcessor {
-
-    private static final Logger LOG = Logger.getLogger(PqcProcessor.class);
-    private static final String FEATURE = "camel-pqc";
-
-    @BuildStep
-    FeatureBuildItem feature() {
-        return new FeatureBuildItem(FEATURE);
-    }
-
-    /**
-     * Remove this once this extension starts supporting the native mode.
-     */
-    @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
-    @Record(value = ExecutionTime.RUNTIME_INIT)
-    void warnJvmInNative(JvmOnlyRecorder recorder) {
-        JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time
-        recorder.warnJvmInNative(FEATURE); // warn at runtime
-    }
-}
diff --git 
a/integration-tests-jvm/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcTest.java
 
b/extensions-support/bouncycastle/deployment/src/main/java/org/apache/camel/quarkus/support/bouncycastle/deployment/BouncyCastleAdditionalProviderBuildItem.java
similarity index 59%
copy from 
integration-tests-jvm/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcTest.java
copy to 
extensions-support/bouncycastle/deployment/src/main/java/org/apache/camel/quarkus/support/bouncycastle/deployment/BouncyCastleAdditionalProviderBuildItem.java
index ff955411d3..c004eca4cf 100644
--- 
a/integration-tests-jvm/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcTest.java
+++ 
b/extensions-support/bouncycastle/deployment/src/main/java/org/apache/camel/quarkus/support/bouncycastle/deployment/BouncyCastleAdditionalProviderBuildItem.java
@@ -14,21 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.pqc.it;
+package org.apache.camel.quarkus.support.bouncycastle.deployment;
 
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import io.quarkus.builder.item.MultiBuildItem;
 
-@QuarkusTest
-class PqcTest {
+/**
+ * In case that non-default BC provider has to be registered, use this 
buildItem.
+ * (provider available for registration is `BCPQC`)
+ */
+public final class BouncyCastleAdditionalProviderBuildItem extends 
MultiBuildItem {
+
+    private final String proivderName;
 
-    @Test
-    public void loadComponentPqc() {
-        /* A simple autogenerated test */
-        RestAssured.get("/pqc/load/component/pqc")
-                .then()
-                .statusCode(200);
+    public BouncyCastleAdditionalProviderBuildItem(String providerNme) {
+        this.proivderName = providerNme;
     }
 
+    public String getProviderName() {
+        return proivderName;
+    }
 }
diff --git 
a/extensions-support/bouncycastle/deployment/src/main/java/org/apache/camel/quarkus/support/bouncycastle/deployment/BouncyCastleSupportProcessor.java
 
b/extensions-support/bouncycastle/deployment/src/main/java/org/apache/camel/quarkus/support/bouncycastle/deployment/BouncyCastleSupportProcessor.java
index a6e47238aa..012b6e73b2 100644
--- 
a/extensions-support/bouncycastle/deployment/src/main/java/org/apache/camel/quarkus/support/bouncycastle/deployment/BouncyCastleSupportProcessor.java
+++ 
b/extensions-support/bouncycastle/deployment/src/main/java/org/apache/camel/quarkus/support/bouncycastle/deployment/BouncyCastleSupportProcessor.java
@@ -26,7 +26,6 @@ import io.quarkus.deployment.annotations.BuildStep;
 import io.quarkus.deployment.annotations.ExecutionTime;
 import io.quarkus.deployment.annotations.Record;
 import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
-import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
 import 
io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
 import io.quarkus.security.deployment.BouncyCastleProviderBuildItem;
@@ -46,12 +45,17 @@ public class BouncyCastleSupportProcessor {
 
     @BuildStep()
     @Record(ExecutionTime.STATIC_INIT)
-    public void 
registerBouncyCastleProvider(List<CipherTransformationBuildItem> 
cipherTransformations,
-            BouncyCastleRecorder recorder,
-            ShutdownContextBuildItem shutdownContextBuildItem) {
+    public void registerBouncyCastleProvider(
+            List<BouncyCastleAdditionalProviderBuildItem> 
additionalProviderBuildItems,
+            List<CipherTransformationBuildItem> cipherTransformations,
+            BouncyCastleRecorder recorder) {
+
         List<String> allCipherTransformations = cipherTransformations.stream()
                 .flatMap(c -> 
c.getCipherTransformations().stream()).collect(Collectors.toList());
-        recorder.registerBouncyCastleProvider(allCipherTransformations, 
shutdownContextBuildItem);
+
+        recorder.registerBouncyCastleProvider(
+                
additionalProviderBuildItems.stream().map(BouncyCastleAdditionalProviderBuildItem::getProviderName).toList(),
+                allCipherTransformations);
     }
 
     @BuildStep()
diff --git 
a/extensions-support/bouncycastle/runtime/src/main/java/org/apache/camel/quarkus/support/bouncycastle/BouncyCastleRecorder.java
 
b/extensions-support/bouncycastle/runtime/src/main/java/org/apache/camel/quarkus/support/bouncycastle/BouncyCastleRecorder.java
index e559d1c496..b53a64f717 100644
--- 
a/extensions-support/bouncycastle/runtime/src/main/java/org/apache/camel/quarkus/support/bouncycastle/BouncyCastleRecorder.java
+++ 
b/extensions-support/bouncycastle/runtime/src/main/java/org/apache/camel/quarkus/support/bouncycastle/BouncyCastleRecorder.java
@@ -18,25 +18,33 @@ package org.apache.camel.quarkus.support.bouncycastle;
 
 import java.lang.reflect.InvocationTargetException;
 import java.security.Provider;
-import java.security.Security;
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.crypto.Cipher;
 
-import io.quarkus.runtime.ShutdownContext;
 import io.quarkus.runtime.annotations.Recorder;
 import io.quarkus.security.runtime.SecurityProviderUtils;
+import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
 import org.jboss.logging.Logger;
 
+import static java.security.Security.addProvider;
+import static java.security.Security.getProvider;
+
 @Recorder
 public class BouncyCastleRecorder {
 
     private static final Logger LOG = 
Logger.getLogger(BouncyCastleRecorder.class);
 
-    public void registerBouncyCastleProvider(List<String> 
cipherTransformations, ShutdownContext shutdownContext) {
-        Provider provider = 
Security.getProvider(SecurityProviderUtils.BOUNCYCASTLE_PROVIDER_NAME);
+    public static final String BOUNCYCASTLE_PCQ_PROVIDER_NAME = "BCPCQ";
+
+    public void registerBouncyCastleProvider(
+            List<String> additionalProviders,
+            List<String> cipherTransformations) {
+        List<Provider> registeredProviders = new ArrayList<>();
+        Provider provider = 
getProvider(SecurityProviderUtils.BOUNCYCASTLE_PROVIDER_NAME);
         if (provider == null) {
-            provider = 
Security.getProvider(SecurityProviderUtils.BOUNCYCASTLE_FIPS_PROVIDER_NAME);
+            provider = 
getProvider(SecurityProviderUtils.BOUNCYCASTLE_FIPS_PROVIDER_NAME);
         }
         if (provider == null) {
             // TODO: Fix BuildStep execution order so that this is not required
@@ -44,7 +52,7 @@ public class BouncyCastleRecorder {
             try {
                 provider = (Provider) 
Thread.currentThread().getContextClassLoader()
                         
.loadClass(SecurityProviderUtils.BOUNCYCASTLE_PROVIDER_CLASS_NAME).getConstructor().newInstance();
-                Security.addProvider(provider);
+                addProvider(provider);
             } catch (ClassNotFoundException | InvocationTargetException | 
InstantiationException | IllegalAccessException
                     | NoSuchMethodException e) {
                 try {
@@ -52,7 +60,7 @@ public class BouncyCastleRecorder {
                     provider = (Provider) 
Thread.currentThread().getContextClassLoader()
                             
.loadClass(SecurityProviderUtils.BOUNCYCASTLE_FIPS_PROVIDER_CLASS_NAME).getConstructor()
                             .newInstance();
-                    Security.addProvider(provider);
+                    addProvider(provider);
                 } catch (ClassNotFoundException | InvocationTargetException | 
InstantiationException | IllegalAccessException
                         | NoSuchMethodException e2) {
                     throw new RuntimeException("Neither BC nor BCFIPS provider 
can be registered. \nBC: " + e.getMessage()
@@ -60,6 +68,7 @@ public class BouncyCastleRecorder {
                 }
             }
         }
+        registeredProviders.add(provider);
 
         // Make it explicit to the static analysis that below security 
services should be registered as they are reachable at runtime
         for (String cipherTransformation : cipherTransformations) {
@@ -73,12 +82,20 @@ public class BouncyCastleRecorder {
             }
         }
 
-        shutdownContext.addShutdownTask(new Runnable() {
-            @Override
-            public void run() {
-                
Security.removeProvider(SecurityProviderUtils.BOUNCYCASTLE_PROVIDER_NAME);
-                LOG.debug("Removed Bouncy Castle security provider");
+        if (additionalProviders.contains(BOUNCYCASTLE_PCQ_PROVIDER_NAME)) {
+            Provider pqcProvider = getProvider("BCPQC");
+            if (pqcProvider == null) {
+                pqcProvider = new BouncyCastlePQCProvider();
+                try {
+                    addProvider(pqcProvider);
+                } catch (SecurityException e) {
+                    throw new RuntimeException(e);
+                }
+                LOG.debugf("Registered BouncyCastlePQCProvider");
             }
-        });
+            registeredProviders.add(pqcProvider);
+
+        }
+
     }
 }
diff --git a/extensions/pom.xml b/extensions/pom.xml
index edcc530261..c5956445c9 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -233,6 +233,7 @@
         <module>pgevent</module>
         <module>pinecone</module>
         <module>platform-http</module>
+        <module>pqc</module>
         <module>protobuf</module>
         <module>pubnub</module>
         <module>qdrant</module>
diff --git a/extensions-jvm/pqc/deployment/pom.xml 
b/extensions/pqc/deployment/pom.xml
similarity index 93%
rename from extensions-jvm/pqc/deployment/pom.xml
rename to extensions/pqc/deployment/pom.xml
index 1c046ba848..0c70adc24d 100644
--- a/extensions-jvm/pqc/deployment/pom.xml
+++ b/extensions/pqc/deployment/pom.xml
@@ -38,6 +38,10 @@
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-pqc</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            
<artifactId>camel-quarkus-support-bouncycastle-deployment</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/extensions/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java
 
b/extensions/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java
new file mode 100644
index 0000000000..425d492964
--- /dev/null
+++ 
b/extensions/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.camel.quarkus.component.pqc.deployment;
+
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
+import 
io.quarkus.deployment.builditem.nativeimage.NativeImageSecurityProviderBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import org.apache.camel.quarkus.support.bouncycastle.BouncyCastleRecorder;
+import 
org.apache.camel.quarkus.support.bouncycastle.deployment.BouncyCastleAdditionalProviderBuildItem;
+import org.jboss.jandex.IndexView;
+import org.jboss.logging.Logger;
+
+class PqcProcessor {
+
+    private static final Logger LOG = Logger.getLogger(PqcProcessor.class);
+    private static final String FEATURE = "camel-pqc";
+
+    @BuildStep
+    FeatureBuildItem feature() {
+        return new FeatureBuildItem(FEATURE);
+    }
+
+    @BuildStep
+    NativeImageSecurityProviderBuildItem registerBcpqcSecurityProvider() {
+        return new 
NativeImageSecurityProviderBuildItem("org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider");
+    }
+
+    @BuildStep
+    IndexDependencyBuildItem indexBouncyCastlePQC() {
+        return new IndexDependencyBuildItem("org.bouncycastle", 
"bcprov-jdk18on");
+    }
+
+    @BuildStep
+    ReflectiveClassBuildItem 
registerBouncyCastlePQCClasses(CombinedIndexBuildItem combinedIndex) {
+        IndexView index = combinedIndex.getIndex();
+
+        String[] pqcClasses = index.getKnownClasses().stream()
+                .map(ci -> ci.name().toString())
+                .filter(
+                        n -> 
(n.startsWith("org.bouncycastle.pqc.jcajce.provider")
+                                && (n.endsWith("Spi") || n.contains("Spi$"))))
+                .toArray(String[]::new);
+
+        return 
ReflectiveClassBuildItem.builder(pqcClasses).methods().fields().build();
+    }
+
+    @BuildStep
+    void registerCryptoClasses(BuildProducer<ReflectiveClassBuildItem> 
reflectiveClasses) {
+        reflectiveClasses.produce(
+                ReflectiveClassBuildItem.builder(
+                        java.security.KeyPairGenerator.class,
+                        java.security.Signature.class,
+                        java.security.KeyFactory.class,
+                        javax.crypto.KeyGenerator.class,
+                        javax.crypto.SecretKey.class).methods().build());
+    }
+
+    @BuildStep
+    BouncyCastleAdditionalProviderBuildItem registerBouncyCastlePQCProvider() {
+        return new 
BouncyCastleAdditionalProviderBuildItem(BouncyCastleRecorder.BOUNCYCASTLE_PCQ_PROVIDER_NAME);
+    }
+
+}
diff --git a/extensions-jvm/pqc/pom.xml b/extensions/pqc/pom.xml
similarity index 96%
rename from extensions-jvm/pqc/pom.xml
rename to extensions/pqc/pom.xml
index 8b2520b670..7290384ab2 100644
--- a/extensions-jvm/pqc/pom.xml
+++ b/extensions/pqc/pom.xml
@@ -21,7 +21,7 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.camel.quarkus</groupId>
-        <artifactId>camel-quarkus-extensions-jvm</artifactId>
+        <artifactId>camel-quarkus-extensions</artifactId>
         <version>3.35.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
diff --git a/extensions-jvm/pqc/runtime/pom.xml b/extensions/pqc/runtime/pom.xml
similarity index 93%
rename from extensions-jvm/pqc/runtime/pom.xml
rename to extensions/pqc/runtime/pom.xml
index 191cfbef83..9c46a0a174 100644
--- a/extensions-jvm/pqc/runtime/pom.xml
+++ b/extensions/pqc/runtime/pom.xml
@@ -32,6 +32,7 @@
 
     <properties>
         <camel.quarkus.jvmSince>3.24.0</camel.quarkus.jvmSince>
+        <camel.quarkus.nativeSince>3.35.0</camel.quarkus.nativeSince>
     </properties>
 
     <dependencies>
@@ -43,6 +44,10 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-pqc</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-support-bouncycastle</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/extensions-jvm/pqc/runtime/src/main/resources/META-INF/quarkus-extension.yaml 
b/extensions/pqc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 98%
rename from 
extensions-jvm/pqc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to 
extensions/pqc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 8dba5652fd..00f74799d4 100644
--- 
a/extensions-jvm/pqc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/pqc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -26,7 +26,6 @@ description: "Post Quantum Computing Signature and 
Verification component"
 metadata:
   icon-url: 
"https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg";
   sponsor: "Apache Software Foundation"
-  unlisted: true
   guide: 
"https://camel.apache.org/camel-quarkus/latest/reference/extensions/pqc.html";
   categories:
   - "integration"
diff --git a/integration-tests-jvm/pom.xml b/integration-tests-jvm/pom.xml
index a1f1237b89..33ae81867c 100644
--- a/integration-tests-jvm/pom.xml
+++ b/integration-tests-jvm/pom.xml
@@ -83,7 +83,6 @@
         <module>main-devmode</module>
         <module>mvel</module>
         <module>opensearch</module>
-        <module>pqc</module>
         <module>printer</module>
         <module>pulsar</module>
         <module>python</module>
diff --git 
a/integration-tests-jvm/pqc/src/main/java/org/apache/camel/quarkus/component/pqc/it/PqcResource.java
 
b/integration-tests-jvm/pqc/src/main/java/org/apache/camel/quarkus/component/pqc/it/PqcResource.java
deleted file mode 100644
index 3824d6ceba..0000000000
--- 
a/integration-tests-jvm/pqc/src/main/java/org/apache/camel/quarkus/component/pqc/it/PqcResource.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-package org.apache.camel.quarkus.component.pqc.it;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import org.apache.camel.CamelContext;
-import org.jboss.logging.Logger;
-
-@Path("/pqc")
-@ApplicationScoped
-public class PqcResource {
-
-    private static final Logger LOG = Logger.getLogger(PqcResource.class);
-
-    private static final String COMPONENT_PQC = "pqc";
-    @Inject
-    CamelContext context;
-
-    @Path("/load/component/pqc")
-    @GET
-    @Produces(MediaType.TEXT_PLAIN)
-    public Response loadComponentPqc() throws Exception {
-        /* This is an autogenerated test */
-        if (context.getComponent(COMPONENT_PQC) != null) {
-            return Response.ok().build();
-        }
-        LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_PQC);
-        return Response.status(500, COMPONENT_PQC + " could not be loaded from 
the Camel context").build();
-    }
-}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 7f277bbdef..b9d959a23a 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -206,6 +206,7 @@
         <module>platform-http</module>
         <module>platform-http-proxy</module>
         <module>platform-http-proxy-ssl</module>
+        <module>pqc</module>
         <module>protobuf</module>
         <module>pubnub</module>
         <module>qdrant</module>
diff --git a/integration-tests-jvm/pqc/pom.xml b/integration-tests/pqc/pom.xml
similarity index 72%
rename from integration-tests-jvm/pqc/pom.xml
rename to integration-tests/pqc/pom.xml
index eb554db9df..aa6451218f 100644
--- a/integration-tests-jvm/pqc/pom.xml
+++ b/integration-tests/pqc/pom.xml
@@ -39,6 +39,10 @@
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-resteasy</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy-jackson</artifactId>
+        </dependency>
 
         <!-- test dependencies -->
         <dependency>
@@ -51,6 +55,11 @@
             <artifactId>rest-assured</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <profiles>
@@ -78,5 +87,32 @@
                 </dependency>
             </dependencies>
         </profile>
+        <profile>
+            <id>native</id>
+            <activation>
+                <property>
+                    <name>native</name>
+                </property>
+            </activation>
+            <properties>
+                <quarkus.native.enabled>true</quarkus.native.enabled>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
     </profiles>
 </project>
diff --git 
a/integration-tests/pqc/src/main/java/org/apache/camel/quarkus/component/pqc/it/PqcProducers.java
 
b/integration-tests/pqc/src/main/java/org/apache/camel/quarkus/component/pqc/it/PqcProducers.java
new file mode 100644
index 0000000000..076b329a68
--- /dev/null
+++ 
b/integration-tests/pqc/src/main/java/org/apache/camel/quarkus/component/pqc/it/PqcProducers.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.camel.quarkus.component.pqc.it;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import jakarta.enterprise.inject.Produces;
+import jakarta.inject.Named;
+import jakarta.inject.Singleton;
+import org.bouncycastle.pqc.crypto.lms.LMOtsParameters;
+import org.bouncycastle.pqc.crypto.lms.LMSigParameters;
+import org.bouncycastle.pqc.jcajce.spec.*;
+
+@Singleton
+public class PqcProducers {
+
+    //not-static to avoid buildtime initialization
+    private final SecureRandom secureRandom = new SecureRandom();
+
+    @Produces
+    @Singleton
+    @Named("dilithiumKeyPair")
+    KeyPair dilithiumKeyPair() throws Exception {
+        return generateKeyPair("Dilithium", DilithiumParameterSpec.dilithium2);
+    }
+
+    @Produces
+    @Singleton
+    @Named("falconKeyPair")
+    public KeyPair falconKeyPair() throws Exception {
+        return generateKeyPair("Falcon", FalconParameterSpec.falcon_512);
+    }
+
+    @Produces
+    @Singleton
+    @Named("sphincsKeyPair")
+    public KeyPair sphincsKeyPair() throws Exception {
+        return generateKeyPair("SPHINCSPlus", 
SPHINCSPlusParameterSpec.sha2_128f);
+    }
+
+    @Produces
+    @Singleton
+    @Named("lmsKeyPair")
+    public KeyPair lmsKeyPair() throws Exception {
+        return generateKeyPair("LMS", new 
LMSParameterSpec(LMSigParameters.lms_sha256_n32_h5, 
LMOtsParameters.sha256_n32_w4));
+    }
+
+    @Produces
+    @Singleton
+    @Named("xmssKeyPair")
+    public KeyPair xmssKeyPair() throws Exception {
+        return generateKeyPair("XMSS", XMSSParameterSpec.SHA2_10_256);
+    }
+
+    @Produces
+    @Singleton
+    @Named("kyberKeyPair")
+    public KeyPair kyberKeyPair() throws Exception {
+        return generateKeyPair("Kyber", KyberParameterSpec.kyber512);
+    }
+
+    @Produces
+    @Singleton
+    @Named("kyberWrongKeyPair") //second keypair for negative scenario
+    public KeyPair kyberWrongKeyPair() throws Exception {
+        return generateKeyPair("Kyber", KyberParameterSpec.kyber512);
+    }
+
+    private KeyPair generateKeyPair(String algorithm, AlgorithmParameterSpec 
spec) throws Exception {
+        KeyPairGenerator gen = KeyPairGenerator.getInstance(algorithm, 
"BCPQC");
+        gen.initialize(spec, secureRandom);
+        return gen.generateKeyPair();
+    }
+}
diff --git 
a/integration-tests/pqc/src/main/java/org/apache/camel/quarkus/component/pqc/it/PqcResource.java
 
b/integration-tests/pqc/src/main/java/org/apache/camel/quarkus/component/pqc/it/PqcResource.java
new file mode 100644
index 0000000000..5fdc95c8c0
--- /dev/null
+++ 
b/integration-tests/pqc/src/main/java/org/apache/camel/quarkus/component/pqc/it/PqcResource.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.camel.quarkus.component.pqc.it;
+
+import java.nio.charset.StandardCharsets;
+import java.security.KeyPair;
+import java.security.Security;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.spec.SecretKeySpec;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.core.MediaType;
+import org.apache.camel.Exchange;
+import org.apache.camel.ProducerTemplate;
+import org.bouncycastle.jcajce.SecretKeyWithEncapsulation;
+import org.jboss.logging.Logger;
+
+@Path("/pqc")
+@ApplicationScoped
+public class PqcResource {
+
+    private static final Logger LOG = Logger.getLogger(PqcResource.class);;
+
+    @Inject
+    @Named("kyberKeyPair")
+    KeyPair kyberKeyPair;
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    @Path("/sign/{algorithm}")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @jakarta.ws.rs.Produces(MediaType.TEXT_PLAIN)
+    public String sign(String message, @PathParam("algorithm") String 
algorithm) {
+        Exchange exchange = producerTemplate.request(
+                
"pqc:sign?operation=sign&signatureAlgorithm=%s&keyPair=%s".formatted(algorithm, 
toKeyPair(algorithm)),
+                ex -> 
ex.getIn().setBody(message.getBytes(StandardCharsets.UTF_8)));
+
+        // The sign operation outputs signature in the HEADER, not the body
+        byte[] signature = 
exchange.getMessage().getHeader("CamelPQCSignature", byte[].class);
+        return Base64.getEncoder().encodeToString(signature);
+    }
+
+    @Path("/verify/{algorithm}/{message}")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @jakarta.ws.rs.Produces(MediaType.TEXT_PLAIN)
+    public boolean verify(String signature,
+            @PathParam("algorithm") String algorithm,
+            @PathParam("message") String message) {
+        byte[] signatureBytes = Base64.getDecoder().decode(signature);
+
+        Map<String, Object> headers = new HashMap<>();
+        headers.put("CamelPQCSignature", signatureBytes);
+
+        Exchange exchange = producerTemplate.request(
+                
"pqc:verify?operation=verify&signatureAlgorithm=%s&keyPair=%s".formatted(algorithm,
 toKeyPair(algorithm)),
+                ex -> {
+                    
ex.getIn().setBody(message.getBytes(StandardCharsets.UTF_8));
+                    ex.getIn().setHeaders(headers);
+                });
+
+        Object verification = 
exchange.getMessage().getHeader("CamelPQCVerification");
+        return Boolean.TRUE.equals(verification);
+    }
+
+    @Path("/kem/encapsulate/{algorithm}/{keyAlgorithm}/{length}")
+    @POST
+    @jakarta.ws.rs.Produces(MediaType.APPLICATION_JSON)
+    public Map<String, String> encapsulate(@PathParam("algorithm") String 
algorithm,
+            @PathParam("keyAlgorithm") String keyAlgorithm,
+            @PathParam("length") int length) {
+        SecretKeyWithEncapsulation secretKeyWithEncapsulation = 
producerTemplate.requestBody(
+                
"pqc:encapsulate?operation=generateSecretKeyEncapsulation&keyEncapsulationAlgorithm=%s&symmetricKeyAlgorithm=%s&symmetricKeyLength=%s&keyPair=%s"
+                        .formatted(algorithm, keyAlgorithm, length, 
toKeyPair(algorithm)),
+                null,
+                SecretKeyWithEncapsulation.class);
+        String enc = 
Base64.getEncoder().encodeToString(secretKeyWithEncapsulation.getEncapsulation());
+        String secret = 
Base64.getEncoder().encodeToString(secretKeyWithEncapsulation.getEncoded());
+        return Map.of("enc", enc, "secret", secret);
+    }
+
+    @Path("/kem/extract/{algorithm}/{keyAlgorithm}/{length}")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @jakarta.ws.rs.Produces(MediaType.TEXT_PLAIN)
+    public String extract(String enc,
+            @PathParam("algorithm") String algorithm,
+            @PathParam("keyAlgorithm") String keyAlgorithm,
+            @PathParam("length") int length) {
+
+        byte[] encapsulation = Base64.getDecoder().decode(enc);
+        //create SecretKeyWithEncapsulation from the private key
+        SecretKeyWithEncapsulation privateKeyWithEncapsulation = new 
SecretKeyWithEncapsulation(
+                new SecretKeySpec(kyberKeyPair.getPrivate().getEncoded(), 
algorithm), encapsulation);
+
+        SecretKeyWithEncapsulation result = producerTemplate.requestBody(
+                
"pqc:extract?operation=extractSecretKeyEncapsulation&keyEncapsulationAlgorithm=%s&symmetricKeyAlgorithm=%s&symmetricKeyLength=%s&keyPair=%s"
+                        .formatted(algorithm, keyAlgorithm, length, 
toKeyPair(algorithm)),
+                privateKeyWithEncapsulation,
+                SecretKeyWithEncapsulation.class);
+        return Base64.getEncoder().encodeToString(result.getEncoded());
+    }
+
+    private String toKeyPair(String algorithm) {
+        return "SPHINCSPLUS".equals(algorithm) ? "#sphincsKeyPair" : "#" + 
algorithm.toLowerCase() + "KeyPair";
+    }
+
+    // Body tests: binary data
+    @Path("/signBinaryData")
+    @POST
+    @jakarta.ws.rs.Produces(MediaType.TEXT_PLAIN)
+    public String signWithBinaryData(String message) {
+        byte[] binaryData = message.getBytes(StandardCharsets.UTF_8);
+
+        Exchange exchange = producerTemplate.request(
+                
"pqc:sign?operation=sign&signatureAlgorithm=DILITHIUM&keyPair=#dilithiumKeyPair",
+                ex -> ex.getIn().setBody(binaryData));
+
+        byte[] signature = 
exchange.getMessage().getHeader("CamelPQCSignature", byte[].class);
+        // Store binary data for verification
+        exchange.getIn().setHeader("CamelTestBinaryData", binaryData);
+        return Base64.getEncoder().encodeToString(signature);
+    }
+
+    @Path("/verifyBinaryData/{message}")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @jakarta.ws.rs.Produces(MediaType.TEXT_PLAIN)
+    public boolean verifyWithBinaryData(String signature,
+            @PathParam("message") String message) {
+        byte[] signatureBytes = Base64.getDecoder().decode(signature);
+        byte[] binaryData = message.getBytes(StandardCharsets.UTF_8);
+
+        Map<String, Object> headers = new HashMap<>();
+        headers.put("CamelPQCSignature", signatureBytes);
+
+        Exchange exchange = producerTemplate.request(
+                
"pqc:verify?operation=verify&signatureAlgorithm=DILITHIUM&keyPair=#dilithiumKeyPair",
+                ex -> {
+                    ex.getIn().setBody(binaryData);
+                    ex.getIn().setHeaders(headers);
+                });
+
+        Object verification = 
exchange.getMessage().getHeader("CamelPQCVerification");
+        return Boolean.TRUE.equals(verification);
+    }
+
+    // Native mode test: check provider
+    @Path("/provider/check")
+    @POST
+    @jakarta.ws.rs.Produces(MediaType.TEXT_PLAIN)
+    public String checkProvider() {
+        java.security.Provider[] providers = Security.getProviders();
+        for (java.security.Provider provider : providers) {
+            if ("BCPQC".equals(provider.getName())) {
+                return "available";
+            }
+        }
+        return "unavailable";
+    }
+
+}
diff --git 
a/integration-tests-jvm/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcTest.java
 
b/integration-tests/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcIT.java
similarity index 71%
rename from 
integration-tests-jvm/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcTest.java
rename to 
integration-tests/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcIT.java
index ff955411d3..e156d72964 100644
--- 
a/integration-tests-jvm/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcTest.java
+++ 
b/integration-tests/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcIT.java
@@ -16,19 +16,8 @@
  */
 package org.apache.camel.quarkus.component.pqc.it;
 
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
-
-@QuarkusTest
-class PqcTest {
-
-    @Test
-    public void loadComponentPqc() {
-        /* A simple autogenerated test */
-        RestAssured.get("/pqc/load/component/pqc")
-                .then()
-                .statusCode(200);
-    }
+import io.quarkus.test.junit.QuarkusIntegrationTest;
 
+@QuarkusIntegrationTest
+class PqcIT extends PqcTest {
 }
diff --git 
a/integration-tests/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcTest.java
 
b/integration-tests/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcTest.java
new file mode 100644
index 0000000000..3acece8d4d
--- /dev/null
+++ 
b/integration-tests/pqc/src/test/java/org/apache/camel/quarkus/component/pqc/it/PqcTest.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.camel.quarkus.component.pqc.it;
+
+import java.util.Map;
+import java.util.stream.Stream;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.apache.camel.component.pqc.PQCKeyEncapsulationAlgorithms;
+import org.apache.camel.component.pqc.PQCSignatureAlgorithms;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+@QuarkusTest
+class PqcTest {
+
+    @ParameterizedTest
+    @EnumSource(value = PQCSignatureAlgorithms.class, names = { "FALCON", 
"DILITHIUM", "SPHINCSPLUS", "XMSS", "LMS" })
+    public void testSignAndVerify(PQCSignatureAlgorithms signatureAlgorithm) {
+        // Sign operation using Falcon algorithm
+        String signature = RestAssured
+                .given()
+                .contentType(ContentType.TEXT)
+                .body("Hello")
+                .post("/pqc/sign/" + signatureAlgorithm.getAlgorithm())
+                .then()
+                .statusCode(200)
+                .extract()
+                .asString();
+
+        assertNotNull(signature);
+        assertFalse(signature.isEmpty());
+
+        // Verify operation using Falcon algorithm
+        RestAssured.given()
+                .contentType("text/plain")
+                .body(signature)
+                .post("/pqc/verify/" + signatureAlgorithm.getAlgorithm() + 
"/Hello")
+                .then()
+                .statusCode(200)
+                .body(equalTo("true"));
+    }
+
+    @Test
+    public void testNegativeSignAndVerify() {
+        // Sign operation using Falcon algorithm
+        String signature = RestAssured
+                .given()
+                .contentType(ContentType.TEXT)
+                .body("Hello")
+                .post("/pqc/sign/" + 
PQCSignatureAlgorithms.DILITHIUM.getAlgorithm())
+                .then()
+                .statusCode(200)
+                .extract()
+                .asString();
+
+        assertThat(signature).isNotBlank();
+
+        // Verify operation using Falcon algorithm
+        RestAssured.given()
+                .contentType("text/plain")
+                .body(signature)
+                .post("/pqc/verify/" + 
PQCSignatureAlgorithms.DILITHIUM.getAlgorithm() + "/Wrong_text")
+                .then()
+                .statusCode(200)
+                .body(equalTo("false"));
+    }
+
+    static Stream<Arguments> encapsulationAlgorithms() {
+        return Stream.of(
+                Arguments.of(PQCKeyEncapsulationAlgorithms.KYBER, "AES", 128),
+                Arguments.of(PQCKeyEncapsulationAlgorithms.KYBER, 
"CHACHA7539", 256));
+    }
+
+    @ParameterizedTest
+    @MethodSource("encapsulationAlgorithms")
+    public void testEncapsulationAndExtract(PQCKeyEncapsulationAlgorithms 
encapsulationAlgorithm, String keyAlgorithm,
+            int length) {
+
+        // Generate encapsulation using Camel PQC component
+        Map<?, ?> map = RestAssured.given()
+                .contentType(ContentType.JSON)
+                .post("/pqc/kem/encapsulate/" + 
encapsulationAlgorithm.getAlgorithm() + "/" + keyAlgorithm + "/" + length)
+                .then()
+                .statusCode(200)
+                .body(notNullValue())
+                .body("secret", notNullValue())
+                .body("enc", notNullValue())
+                .extract()
+                .as(Map.class);
+
+        // Extract secret key from encapsulation using Camel PQC component
+        RestAssured.given()
+                .contentType("text/plain")
+                .body(map.get("enc"))
+                .post("/pqc/kem/extract/" + 
encapsulationAlgorithm.getAlgorithm() + "/" + keyAlgorithm + "/" + length)
+                .then()
+                .statusCode(200)
+                .body(equalTo(map.get("secret")));
+    }
+
+    @Test
+    public void testSignVerifyWithBinaryData() {
+        // Sign and verify with binary data
+        String signature = RestAssured.given()
+                .body("hello")
+                .post("/pqc/signBinaryData")
+                .then()
+                .statusCode(200)
+                .extract()
+                .asString();
+
+        assertNotNull(signature);
+
+        // Verify with same binary data
+        RestAssured.given()
+                .contentType("text/plain")
+                .body(signature)
+                .post("/pqc/verifyBinaryData/hello")
+                .then()
+                .statusCode(200)
+                .body(equalTo("true"));
+    }
+
+    @Test
+    public void testBouncyCastleProviderAvailable() {
+        // Verify BouncyCastlePQCProvider is registered in Security providers
+        RestAssured.post("/pqc/provider/check")
+                .then()
+                .statusCode(200)
+                .body(equalTo("available"));
+    }
+
+}
diff --git a/tooling/scripts/test-categories.yaml 
b/tooling/scripts/test-categories.yaml
index 46575624b7..790327c7a6 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -153,6 +153,7 @@ group-08:
   - master-file
   - pdf
   - pinecone
+  - pqc
   - saxon
   - syndication
   - telegram

Reply via email to