You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by co...@apache.org on 2023/01/20 09:52:06 UTC

[santuario-xml-security-java] branch main updated: Support for EdDSA: Ed25519 and Ed448 (#90)

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

coheigea pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/santuario-xml-security-java.git


The following commit(s) were added to refs/heads/main by this push:
     new 2695e32d Support for EdDSA: Ed25519 and Ed448 (#90)
2695e32d is described below

commit 2695e32d6acde43a0ff9123bd25781b8e28eb63f
Author: jrihtarsic <jr...@gmail.com>
AuthorDate: Fri Jan 20 10:52:00 2023 +0100

    Support for EdDSA: Ed25519 and Ed448 (#90)
    
    * Fix issue when parsing invalid xpointer URI. Code now throws
    XMLSignatureException instead of StringIndexOutOfBoundsException.
    
    * Updating enforcer plugin to 3.0.0
    
    * [SANTUARIO-586]sync JDK-8186958: better calculations for HashMap constructor parameter calculation
    
    * Updating Log4J to 2.17.2
    
    * Updating NOTICE year
    
    * [maven-release-plugin] prepare release xmlsec-2.3.1
    
    * [maven-release-plugin] prepare for next development iteration
    
    * Bumping provider to 2.32 after release
    
    * Updating to Log4J 2.18.0
    
    * Fixing BouncyCastle dependency
    
    * SANTUARIO-593 - Remove here() function support from Apache Santuario (#71)
    
    * SANTUARIO-593 - Remove here() function support from Apache Santuario
    
    * Adding Baltimore23XalanTest
    
    * [maven-release-plugin] prepare release xmlsec-2.3.2
    
    * [maven-release-plugin] prepare for next development iteration
    
    * Updating Version after release
    
    * Fix for https://bugs.openjdk.org/browse/JDK-8287246.
    
    * Updating to Jubit 5.9.1
    
    * Bump woodstox-core from 6.2.8 to 6.4.0 (#80)
    
    Bumps [woodstox-core](https://github.com/FasterXML/woodstox) from 6.2.8 to 6.4.0.
    - [Release notes](https://github.com/FasterXML/woodstox/releases)
    - [Commits](https://github.com/FasterXML/woodstox/compare/woodstox-core-6.2.8...woodstox-core-6.4.0)
    
    ---
    updated-dependencies:
    - dependency-name: com.fasterxml.woodstox:woodstox-core
      dependency-type: direct:production
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <su...@github.com>
    
    Signed-off-by: dependabot[bot] <su...@github.com>
    Co-authored-by: dependabot[bot] <49...@users.noreply.github.com>
    
    * Allow SLF4J 2+ for OSGi
    
    * Bump bcprov-jdk18on from 1.71 to 1.72 (#79)
    
    Bumps [bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.71 to 1.72.
    - [Release notes](https://github.com/bcgit/bc-java/releases)
    - [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html)
    - [Commits](https://github.com/bcgit/bc-java/commits)
    
    ---
    updated-dependencies:
    - dependency-name: org.bouncycastle:bcprov-jdk18on
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <su...@github.com>
    
    Signed-off-by: dependabot[bot] <su...@github.com>
    Co-authored-by: dependabot[bot] <49...@users.noreply.github.com>
    
    * Bump maven-bundle-plugin from 5.1.4 to 5.1.8 (#72)
    
    Bumps maven-bundle-plugin from 5.1.4 to 5.1.8.
    
    ---
    updated-dependencies:
    - dependency-name: org.apache.felix:maven-bundle-plugin
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <su...@github.com>
    
    Signed-off-by: dependabot[bot] <su...@github.com>
    Co-authored-by: dependabot[bot] <49...@users.noreply.github.com>
    
    * Bump maven-compiler-plugin from 3.8.1 to 3.10.1 (#74)
    
    Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.8.1 to 3.10.1.
    - [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
    - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.8.1...maven-compiler-plugin-3.10.1)
    
    ---
    updated-dependencies:
    - dependency-name: org.apache.maven.plugins:maven-compiler-plugin
      dependency-type: direct:production
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <su...@github.com>
    
    Signed-off-by: dependabot[bot] <su...@github.com>
    Co-authored-by: dependabot[bot] <49...@users.noreply.github.com>
    
    * Support for EdDSA: Ed25519 and Ed448
    
    * Fix comments.
    
    * Add tests for EdDSA(Ed22519 and Ed448) XML signature validation.
    Add activation of BouncyCastleProvider for EdDSA tests only when JDK is before the JDK 15.
    
    * Add basic JSR 105 EdDSA signature validation tests
    
    * Add basic JSR 105 EdDSA signature creation tests
    
    * Fix the License headers for new classes
    
    Signed-off-by: dependabot[bot] <su...@github.com>
    Co-authored-by: Sean Mullan <se...@oracle.com>
    Co-authored-by: Colm O hEigeartaigh <co...@apache.org>
    Co-authored-by: XenoAmess <xe...@gmail.com>
    Co-authored-by: Colm O hEigeartaigh <co...@users.noreply.github.com>
    Co-authored-by: dependabot[bot] <49...@users.noreply.github.com>
    Co-authored-by: Joze RIHTARSIC <jo...@ext.ec.europa.eu>
---
 pom.xml                                            |   6 +
 .../internal/dom/AbstractDOMSignatureMethod.java   |   2 +-
 .../xml/dsig/internal/dom/DOMSignatureMethod.java  |  95 +++++++++
 .../dsig/internal/dom/DOMXMLSignatureFactory.java  |   4 +
 .../apache/xml/security/algorithms/JCEMapper.java  |   8 +
 .../security/algorithms/SignatureAlgorithm.java    |  11 +-
 .../algorithms/implementations/SignatureEDDSA.java | 224 ++++++++++++++++++++
 .../org/apache/xml/security/resource/config.xml    |   5 +
 .../xml/security/signature/XMLSignature.java       |   8 +
 .../xml/crypto/test/dsig/EdDSATestAbstract.java    |  70 ++++++
 .../xml/crypto/test/dsig/SignatureValidator.java   |  16 +-
 .../test/dsig/SignatureValidatorEdDSATest.java     |  68 ++++++
 .../crypto/test/dsig/XMLSignatureEdDSATest.java    | 148 +++++++++++++
 .../test/dom/signature/EDDSASignatureTest.java     | 235 +++++++++++++++++++++
 .../eddsa/envelopingInvalidSignatureEd25519.xml    |  31 +++
 .../dsig/eddsa/envelopingInvalidSignatureEd448.xml |  32 +++
 .../dsig/eddsa/envelopingSignatureEd25519.xml      |  31 +++
 .../crypto/dsig/eddsa/envelopingSignatureEd448.xml |  32 +++
 .../apache/xml/security/samples/input/eddsa.p12    | Bin 0 -> 1977 bytes
 .../samples/input/eddsaEd25519Signature.xml        |  34 +++
 .../security/samples/input/eddsaEd448Signature.xml |  35 +++
 21 files changed, 1086 insertions(+), 9 deletions(-)

diff --git a/pom.xml b/pom.xml
index c9339fb8..c063d23a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -589,6 +589,12 @@
             <version>${junit.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.xmlunit</groupId>
             <artifactId>xmlunit-core</artifactId>
diff --git a/src/main/java/org/apache/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java b/src/main/java/org/apache/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java
index 7bb19c0e..b81cb99a 100644
--- a/src/main/java/org/apache/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java
+++ b/src/main/java/org/apache/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java
@@ -45,7 +45,7 @@ abstract class AbstractDOMSignatureMethod extends DOMStructure
     implements SignatureMethod {
 
     // denotes the type of signature algorithm
-    enum Type { DSA, RSA, ECDSA, HMAC }
+    enum Type { DSA, RSA, ECDSA, EDDSA, HMAC }
 
     /**
      * Verifies the passed-in signature with the specified key, using the
diff --git a/src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java b/src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java
index ef8c9f07..b92b10b3 100644
--- a/src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java
+++ b/src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java
@@ -74,6 +74,12 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
     static final String DSA_SHA256 =
         "http://www.w3.org/2009/xmldsig11#dsa-sha256";
 
+    // see RFC 9231 for these algorithm definitions
+    static final String ED25519 =
+        "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
+    static final String ED448 =
+        "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
+
     // see RFC 6931 for these algorithm definitions
     static final String ECDSA_RIPEMD160 =
         "http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160";
@@ -212,6 +218,10 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
             return new DOMHMACSignatureMethod.SHA512(smElem);
         } else if (alg.equals(DOMHMACSignatureMethod.HMAC_RIPEMD160)) {
             return new DOMHMACSignatureMethod.RIPEMD160(smElem);
+        } else if (alg.equals(ED25519)) {
+            return new EDDSA_ED25519(smElem);
+        } else if (alg.equals(ED448)) {
+            return new EDDSA_ED448(smElem);
         } else {
             throw new MarshalException
                 ("unsupported SignatureMethod algorithm: " + alg);
@@ -469,6 +479,39 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
         }
     }
 
+    abstract static class AbstractEDDSASignatureMethod
+            extends DOMSignatureMethod {
+
+
+        AbstractEDDSASignatureMethod(AlgorithmParameterSpec params)
+                throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+
+        AbstractEDDSASignatureMethod(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+
+        /**
+         * Returns {@code sig}. No extra formatting is necessary for EDDSA
+         * See the RFC8032
+         */
+        @Override
+        byte[] postSignFormat(Key key, byte[] sig) {
+            return sig;
+        }
+
+        /**
+         * Returns {@code sig}. No extra formatting is necessary for EDDSA
+         * See the RFC8032
+         */
+        @Override
+        byte[] preVerifyFormat(Key key, byte[] sig) {
+            return sig;
+        }
+
+    }
+
     static final class SHA1withRSA extends AbstractRSASignatureMethod {
         SHA1withRSA(AlgorithmParameterSpec params)
             throws InvalidAlgorithmParameterException {
@@ -903,4 +946,56 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
         }
     }
 
+    static final class EDDSA_ED25519 extends AbstractEDDSASignatureMethod {
+
+        EDDSA_ED25519(AlgorithmParameterSpec params)
+                throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+
+        EDDSA_ED25519(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+
+        @Override
+        public String getAlgorithm() {
+            return ED25519;
+        }
+
+        @Override
+        String getJCAAlgorithm() {
+            return "Ed25519";
+        }
+
+        @Override
+        Type getAlgorithmType() {
+            return Type.EDDSA;
+        }
+    }
+
+    static final class EDDSA_ED448 extends AbstractEDDSASignatureMethod {
+        EDDSA_ED448(AlgorithmParameterSpec params)
+                throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+
+        EDDSA_ED448(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+
+        @Override
+        public String getAlgorithm() {
+            return ED448;
+        }
+
+        @Override
+        String getJCAAlgorithm() {
+            return "Ed448";
+        }
+
+        @Override
+        Type getAlgorithmType() {
+            return Type.EDDSA;
+        }
+    }
 }
diff --git a/src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java b/src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java
index 2c974ced..1f8b7e56 100644
--- a/src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java
+++ b/src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java
@@ -298,6 +298,10 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
             return new DOMSignatureMethod.SHA512withECDSA(params);
         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_RIPEMD160)) {
             return new DOMSignatureMethod.RIPEMD160withECDSA(params);
+        } else if (algorithm.equals(DOMSignatureMethod.ED25519)) {
+            return new DOMSignatureMethod.EDDSA_ED25519(params);
+        } else if (algorithm.equals(DOMSignatureMethod.ED448)) {
+            return new DOMSignatureMethod.EDDSA_ED448(params);
         }else {
             throw new NoSuchAlgorithmException("unsupported algorithm");
         }
diff --git a/src/main/java/org/apache/xml/security/algorithms/JCEMapper.java b/src/main/java/org/apache/xml/security/algorithms/JCEMapper.java
index 6e054d0b..a91724a7 100644
--- a/src/main/java/org/apache/xml/security/algorithms/JCEMapper.java
+++ b/src/main/java/org/apache/xml/security/algorithms/JCEMapper.java
@@ -206,6 +206,14 @@ public class JCEMapper {
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160,
             new Algorithm("EC", "RIPEMD160withECDSA", "Signature")
         );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519,
+            new Algorithm("Ed25519", "Ed25519", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448,
+            new Algorithm("Ed448", "Ed448", "Signature")
+        );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5,
             new Algorithm("", "HmacMD5", "Mac", 0, 0)
diff --git a/src/main/java/org/apache/xml/security/algorithms/SignatureAlgorithm.java b/src/main/java/org/apache/xml/security/algorithms/SignatureAlgorithm.java
index 519175a5..7db398ef 100644
--- a/src/main/java/org/apache/xml/security/algorithms/SignatureAlgorithm.java
+++ b/src/main/java/org/apache/xml/security/algorithms/SignatureAlgorithm.java
@@ -27,10 +27,7 @@ import java.security.spec.AlgorithmParameterSpec;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.xml.security.algorithms.implementations.IntegrityHmac;
-import org.apache.xml.security.algorithms.implementations.SignatureBaseRSA;
-import org.apache.xml.security.algorithms.implementations.SignatureDSA;
-import org.apache.xml.security.algorithms.implementations.SignatureECDSA;
+import org.apache.xml.security.algorithms.implementations.*;
 import org.apache.xml.security.exceptions.AlgorithmAlreadyRegisteredException;
 import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.signature.XMLSignature;
@@ -493,6 +490,12 @@ public class SignatureAlgorithm extends Algorithm {
         algorithmHash.put(
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160, SignatureECDSA.SignatureECDSARIPEMD160.class
         );
+        algorithmHash.put(
+                XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519, SignatureEDDSA.SignatureEd25519.class
+        );
+        algorithmHash.put(
+                XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448, SignatureEDDSA.SignatureEd448.class
+        );
         algorithmHash.put(
             XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5, IntegrityHmac.IntegrityHmacMD5.class
         );
diff --git a/src/main/java/org/apache/xml/security/algorithms/implementations/SignatureEDDSA.java b/src/main/java/org/apache/xml/security/algorithms/implementations/SignatureEDDSA.java
new file mode 100644
index 00000000..b8921343
--- /dev/null
+++ b/src/main/java/org/apache/xml/security/algorithms/implementations/SignatureEDDSA.java
@@ -0,0 +1,224 @@
+/**
+ * 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.xml.security.algorithms.implementations;
+
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.algorithms.SignatureAlgorithmSpi;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.utils.XMLUtils;
+
+import java.io.IOException;
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ *
+ */
+public abstract class SignatureEDDSA extends SignatureAlgorithmSpi {
+
+    private static final org.slf4j.Logger LOG =
+        org.slf4j.LoggerFactory.getLogger(SignatureEDDSA.class);
+
+    private final Signature signatureAlgorithm;
+
+
+    /**
+     * Constructor SignatureEDDSA
+     *
+     * @throws XMLSignatureException
+     */
+    public SignatureEDDSA() throws XMLSignatureException {
+        this(null);
+    }
+
+    public SignatureEDDSA(Provider provider) throws XMLSignatureException {
+        String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
+        LOG.debug("Created SignatureEDDSA using {}", algorithmID);
+
+        try {
+            if (provider == null) {
+                String providerId = JCEMapper.getProviderId();
+                if (providerId == null) {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID);
+
+                } else {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID, providerId);
+                }
+
+            } else {
+                this.signatureAlgorithm = Signature.getInstance(algorithmID, provider);
+            }
+
+        } catch (NoSuchAlgorithmException | NoSuchProviderException ex) {
+            Object[] exArgs = { algorithmID, ex.getLocalizedMessage() };
+            throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs);
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected void engineSetParameter(AlgorithmParameterSpec params)
+        throws XMLSignatureException {
+        try {
+            this.signatureAlgorithm.setParameter(params);
+        } catch (InvalidAlgorithmParameterException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
+        try {
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Called SignatureEDDSA.verify() on " + XMLUtils.encodeToString(signature));
+            }
+
+            return this.signatureAlgorithm.verify(signature);
+        } catch (SignatureException  ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
+        engineInitVerify(publicKey, signatureAlgorithm);
+    }
+
+    /** {@inheritDoc} */
+    protected byte[] engineSign() throws XMLSignatureException {
+        try {
+            return this.signatureAlgorithm.sign();
+        } catch (SignatureException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
+        throws XMLSignatureException {
+
+        engineInitSign(privateKey, secureRandom, this.signatureAlgorithm);
+    }
+
+    /** {@inheritDoc} */
+    protected void engineInitSign(Key privateKey) throws XMLSignatureException {
+        engineInitSign(privateKey, (SecureRandom)null);
+    }
+
+    /** {@inheritDoc} */
+    protected void engineUpdate(byte[] input) throws XMLSignatureException {
+        try {
+            this.signatureAlgorithm.update(input);
+        } catch (SignatureException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected void engineUpdate(byte input) throws XMLSignatureException {
+        try {
+            this.signatureAlgorithm.update(input);
+        } catch (SignatureException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected void engineUpdate(byte[] buf, int offset, int len) throws XMLSignatureException {
+        try {
+            this.signatureAlgorithm.update(buf, offset, len);
+        } catch (SignatureException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected String engineGetJCEAlgorithmString() {
+        return this.signatureAlgorithm.getAlgorithm();
+    }
+
+    /** {@inheritDoc} */
+    protected String engineGetJCEProviderName() {
+        return this.signatureAlgorithm.getProvider().getName();
+    }
+
+    /** {@inheritDoc} */
+    protected void engineSetHMACOutputLength(int HMACOutputLength)
+        throws XMLSignatureException {
+        throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
+    }
+
+    /** {@inheritDoc} */
+    protected void engineInitSign(
+        Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
+    ) throws XMLSignatureException {
+        throw new XMLSignatureException("algorithms.CannotUseAlgorithmParameterSpecOnEdDSA");
+    }
+
+    /**
+     * Class SignatureEd25519
+     *
+     */
+    public static class SignatureEd25519 extends SignatureEDDSA {
+        /**
+         * Constructor SignatureEd25519
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureEd25519() throws XMLSignatureException {
+            super();
+        }
+
+        public SignatureEd25519(Provider provider) throws XMLSignatureException {
+            super(provider);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519;
+        }
+    }
+
+    /**
+     * Class SignatureEd448
+     */
+    public static class SignatureEd448 extends SignatureEDDSA {
+
+        /**
+         * Constructor SignatureEd448
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureEd448() throws XMLSignatureException {
+            super();
+        }
+
+        public SignatureEd448(Provider provider) throws XMLSignatureException {
+            super(provider);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/xml/security/resource/config.xml b/src/main/java/org/apache/xml/security/resource/config.xml
index e460eb64..326140ee 100644
--- a/src/main/java/org/apache/xml/security/resource/config.xml
+++ b/src/main/java/org/apache/xml/security/resource/config.xml
@@ -128,6 +128,11 @@
                           JAVACLASS="org.apache.xml.security.algorithms.implementations.SignatureECDSA$SignatureECDSASHA512" />
       <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160"
                           JAVACLASS="org.apache.xml.security.algorithms.implementations.SignatureECDSA$SignatureECDSARIPEMD160" />
+
+      <SignatureAlgorithm URI="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519"
+                          JAVACLASS="org.apache.xml.security.algorithms.implementations.SignatureEDDSA$SignatureEd25519" />
+      <SignatureAlgorithm URI="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448"
+                          JAVACLASS="org.apache.xml.security.algorithms.implementations.SignatureEDDSA$SignatureEd448" />
                           
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-md5"
                           JAVACLASS="org.apache.xml.security.algorithms.implementations.IntegrityHmac$IntegrityHmacMD5" />
diff --git a/src/main/java/org/apache/xml/security/signature/XMLSignature.java b/src/main/java/org/apache/xml/security/signature/XMLSignature.java
index 4987431a..19801c04 100644
--- a/src/main/java/org/apache/xml/security/signature/XMLSignature.java
+++ b/src/main/java/org/apache/xml/security/signature/XMLSignature.java
@@ -197,6 +197,14 @@ public final class XMLSignature extends SignatureElementProxy {
     public static final String ALGO_ID_SIGNATURE_ECDSA_RIPEMD160 =
         "http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160";
 
+    /**Signature - EDDSA ED25519 */
+    public static final String ALGO_ID_SIGNATURE_EDDSA_ED25519 =
+            "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
+
+    /**Signature - EDDSA ED448 */
+    public static final String ALGO_ID_SIGNATURE_EDDSA_ED448 =
+            "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
+
     /** Signature - Optional RSASSA-PSS */
     public static final String ALGO_ID_SIGNATURE_RSA_PSS =
             Constants.XML_DSIG_NS_MORE_07_05 + "rsa-pss";
diff --git a/src/test/java/javax/xml/crypto/test/dsig/EdDSATestAbstract.java b/src/test/java/javax/xml/crypto/test/dsig/EdDSATestAbstract.java
new file mode 100644
index 00000000..c5b7a5d5
--- /dev/null
+++ b/src/test/java/javax/xml/crypto/test/dsig/EdDSATestAbstract.java
@@ -0,0 +1,70 @@
+/**
+ * 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 javax.xml.crypto.test.dsig;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import java.security.Security;
+
+/**
+ * Abstract/super class for EdDSA signature tests
+ */
+public abstract class EdDSATestAbstract {
+
+    public static final String EDDSA_KS =
+            "src/test/resources/org/apache/xml/security/samples/input/eddsa.p12";
+    public static final String EDDSA_KS_PASSWORD = "security";
+    public static final String EDDSA_KS_TYPE = "PKCS12";
+    private static boolean bcAddedForTheTest = false;
+
+    @org.junit.jupiter.api.BeforeAll
+    public static void beforeAll() {
+        Security.insertProviderAt
+                (new org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI(), 1);
+        // Since JDK 15, the EdDSA algorithms are supported in the default java JCA provider.
+        // Add BouncyCastleProvider only for java versions before JDK 15.
+        boolean isNotJDK15up;
+        try {
+            int javaVersion = Integer.parseInt(System.getProperty("java.specification.version"));
+            isNotJDK15up = javaVersion < 15;
+        } catch (NumberFormatException ex) {
+            isNotJDK15up = true;
+        }
+        if (isNotJDK15up && Security.getProvider(org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME) == null) {
+            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+            bcAddedForTheTest = true;
+        }
+    }
+
+    @org.junit.jupiter.api.AfterAll
+    public static void afterAll() {
+        if (bcAddedForTheTest) {
+            Security.removeProvider(org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME);
+        }
+    }
+
+    public void updateIdReferences(DOMValidateContext vc, String elementName, String idAttributeName) {
+        Document doc = vc.getNode().getOwnerDocument();
+        NodeList nl = doc.getElementsByTagName(elementName);
+        vc.setIdAttributeNS((Element) nl.item(0), null, idAttributeName);
+    }
+}
diff --git a/src/test/java/javax/xml/crypto/test/dsig/SignatureValidator.java b/src/test/java/javax/xml/crypto/test/dsig/SignatureValidator.java
index 1d001d41..b3bd195d 100644
--- a/src/test/java/javax/xml/crypto/test/dsig/SignatureValidator.java
+++ b/src/test/java/javax/xml/crypto/test/dsig/SignatureValidator.java
@@ -54,15 +54,23 @@ public class SignatureValidator {
         return getValidateContext(fn, ks, true);
     }
 
-    public DOMValidateContext getValidateContext(String fn, KeySelector ks, boolean secureValidation)
-        throws Exception {
-        Document doc = XMLUtils.read(new FileInputStream(new File(dir, fn)), false);
+    public DOMValidateContext getValidateContext(String fn, KeySelector ks, boolean secureValidation) throws Exception {
+        DOMValidateContext domValidateContext;
+        try (FileInputStream inputStream = new FileInputStream(new File(dir, fn))){
+            domValidateContext =  getValidateContext(inputStream, ks, secureValidation);
+            domValidateContext.setBaseURI(dir.toURI().toString());
+        }
+        return domValidateContext;
+    }
+
+    public DOMValidateContext getValidateContext(InputStream inputStream, KeySelector ks, boolean secureValidation)
+            throws Exception {
+        Document doc = XMLUtils.read(inputStream, false);
         Element sigElement = getSignatureElement(doc);
         if (sigElement == null) {
             throw new Exception("Couldn't find signature Element");
         }
         DOMValidateContext vc = new DOMValidateContext(ks, sigElement);
-        vc.setBaseURI(dir.toURI().toString());
         vc.setProperty("org.apache.jcp.xml.dsig.secureValidation", secureValidation);
         return vc;
     }
diff --git a/src/test/java/javax/xml/crypto/test/dsig/SignatureValidatorEdDSATest.java b/src/test/java/javax/xml/crypto/test/dsig/SignatureValidatorEdDSATest.java
new file mode 100644
index 00000000..dca8fe8c
--- /dev/null
+++ b/src/test/java/javax/xml/crypto/test/dsig/SignatureValidatorEdDSATest.java
@@ -0,0 +1,68 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 javax.xml.crypto.test.dsig;
+
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.crypto.test.KeySelectors;
+import java.nio.file.Paths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+
+/**
+ * This is a testcase validates various EdDSA XML signatures
+ */
+public class SignatureValidatorEdDSATest extends EdDSATestAbstract {
+
+    private SignatureValidator testInstance;
+
+    @org.junit.jupiter.api.BeforeEach
+    public void before() {
+        String base = System.getProperty("basedir", "./");
+        testInstance = new SignatureValidator(Paths.get(base, "src", "test", "resources", "javax", "xml", "crypto", "dsig", "eddsa").toFile());
+    }
+
+    /**
+     * Validates a signature that references an element with an ID attribute.
+     * The element's ID needs to be registered so that it can be found.
+     */
+    @ParameterizedTest
+    @CsvSource({"envelopingSignatureEd25519.xml,true,Signature failed core validation",
+            "envelopingSignatureEd448.xml,true,Signature failed core validation",
+            "envelopingInvalidSignatureEd25519.xml,false,Invalid signature should fail!",
+            "envelopingInvalidSignatureEd448.xml,false,Invalid signature should fail!"})
+    public void test_enveloping_signature_with_ID(String filename, String result, String message) throws Exception {
+        DOMValidateContext vc = testInstance.getValidateContext
+                (filename, new KeySelectors.RawX509KeySelector());
+        updateIdReferences(vc);
+
+        boolean coreValidity = testInstance.validate(vc);
+        // assert expected result
+        assertEquals(Boolean.valueOf(result), coreValidity, message);
+    }
+
+    private void updateIdReferences(DOMValidateContext vc) {
+        updateIdReferences(vc, "Assertion", "AssertionID");
+    }
+
+}
diff --git a/src/test/java/javax/xml/crypto/test/dsig/XMLSignatureEdDSATest.java b/src/test/java/javax/xml/crypto/test/dsig/XMLSignatureEdDSATest.java
new file mode 100644
index 00000000..d4300e97
--- /dev/null
+++ b/src/test/java/javax/xml/crypto/test/dsig/XMLSignatureEdDSATest.java
@@ -0,0 +1,148 @@
+/**
+ * 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 javax.xml.crypto.test.dsig;
+
+
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.test.dom.TestUtils;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.w3c.dom.Element;
+
+import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.keyinfo.X509Data;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+import javax.xml.crypto.test.KeySelectors;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+
+/**
+ * Unit test for EdDSA javax.xml.crypto.dsig.XMLSignature creation
+ */
+public class XMLSignatureEdDSATest extends EdDSATestAbstract {
+    private final SignatureValidator testInstance = new SignatureValidator(null);
+
+    static {
+        Security.insertProviderAt
+                (new org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI(), 1);
+    }
+
+    @ParameterizedTest
+    @CsvSource({"http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519,ed25519",
+            "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448,ed448",
+    })
+    public void createEdDSASignatureTest(String signatureAlgorithm, String alias) throws Exception {
+        byte[] buff = doSign(signatureAlgorithm, alias);
+        Assertions.assertNotNull(buff);
+        assertValidSignature(buff);
+    }
+
+    public byte[] doSign(String signatureMethod, String alias) throws Exception {
+
+        // create test xml document to sign
+        String signedElementId = "element-id-01";
+        String signedElementName = "SignedElement";
+        org.w3c.dom.Document doc = TestUtils.newDocument();
+        Element root = doc.createElement("RootElement");
+        Element signedElement = doc.createElement(signedElementName);
+        signedElement.setAttribute("id", signedElementId);
+        signedElement.appendChild(doc.createTextNode("Some data to sign"));
+        doc.appendChild(root);
+        root.appendChild(signedElement);
+
+        // get private key and the certificate from the truststore
+        KeyStore keyStore = KeyStore.getInstance(EDDSA_KS_TYPE);
+        keyStore.load(Files.newInputStream(Paths.get(EDDSA_KS)), EDDSA_KS_PASSWORD.toCharArray());
+        X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias);
+        PrivateKey privateKey =
+                (PrivateKey) keyStore.getKey(alias, EDDSA_KS_PASSWORD.toCharArray());
+
+        // prepare xml signature data
+        Element canonElem =
+                XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_CANONICALIZATIONMETHOD);
+        canonElem.setAttributeNS(
+                null, Constants._ATT_ALGORITHM, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS
+        );
+
+        //Create XML Signature Factory
+        XMLSignatureFactory xmlSigFactory = XMLSignatureFactory.getInstance("DOM");
+        DOMSignContext domSignCtx = new DOMSignContext(privateKey, doc.getDocumentElement());
+        domSignCtx.setIdAttributeNS(signedElement, null, "id");
+        // reference(s), SignedInfo and KeyInfo
+        Reference ref = xmlSigFactory.newReference("#" + signedElementId, xmlSigFactory.newDigestMethod(DigestMethod.SHA256, null),
+                Collections.singletonList(xmlSigFactory.newTransform(Transform.ENVELOPED,
+                        (TransformParameterSpec) null)), null, null);
+        SignedInfo signedInfo = xmlSigFactory.newSignedInfo(
+                xmlSigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
+                        (C14NMethodParameterSpec) null),
+                xmlSigFactory.newSignatureMethod(signatureMethod, null),
+                Collections.singletonList(ref));
+        KeyInfo keyInfo = createKeyInfo(xmlSigFactory, certificate);
+        //Create the XML Signature
+        XMLSignature xmlSignature = xmlSigFactory.newXMLSignature(signedInfo, keyInfo);
+        //Sign the document
+        xmlSignature.sign(domSignCtx);
+        // serialize the xml to byte array
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        XMLUtils.outputDOMc14nWithComments(doc, bos);
+        return bos.toByteArray();
+    }
+
+    private KeyInfo createKeyInfo(XMLSignatureFactory fac, X509Certificate cert) {
+        // Create the KeyInfo containing the X509Data.
+        KeyInfoFactory kif = fac.getKeyInfoFactory();
+        List<Object> x509Content = new ArrayList();
+        x509Content.add(cert.getSubjectX500Principal().getName());
+        x509Content.add(cert);
+        X509Data xd = kif.newX509Data(x509Content);
+        return kif.newKeyInfo(Collections.singletonList(xd));
+    }
+
+    private void assertValidSignature(byte[] signedXml) throws Exception {
+        try (InputStream is = new ByteArrayInputStream(signedXml)) {
+            DOMValidateContext vc = testInstance.getValidateContext(is, new KeySelectors.RawX509KeySelector(), false);
+            updateIdReferences(vc, "SignedElement", "id");
+
+            boolean coreValidity = testInstance.validate(vc);
+            // assert expected result
+            assertTrue(coreValidity);
+        }
+    }
+}
diff --git a/src/test/java/org/apache/xml/security/test/dom/signature/EDDSASignatureTest.java b/src/test/java/org/apache/xml/security/test/dom/signature/EDDSASignatureTest.java
new file mode 100644
index 00000000..3bfe74cc
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/test/dom/signature/EDDSASignatureTest.java
@@ -0,0 +1,235 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.test.dom.signature;
+
+import org.apache.xml.security.algorithms.SignatureAlgorithm;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.test.dom.DSNamespaceContext;
+import org.apache.xml.security.test.dom.TestUtils;
+import org.apache.xml.security.transforms.Transforms;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.junit.jupiter.api.Assertions;
+import org.w3c.dom.Element;
+
+import javax.xml.crypto.test.dsig.EdDSATestAbstract;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+
+
+/**
+ * Tests of the EDDSA Ed25519 and Ed448 signatures.
+ * @since 2.3.3.
+ */
+public class EDDSASignatureTest extends EdDSATestAbstract {
+    static {
+        if (!org.apache.xml.security.Init.isInitialized()) {
+            org.apache.xml.security.Init.init();
+        }
+    }
+
+    @org.junit.jupiter.api.Test
+    public void testEd22519() throws Exception {
+
+        KeyStore keyStore = KeyStore.getInstance(EDDSA_KS_TYPE);
+        keyStore.load(Files.newInputStream(Paths.get(EDDSA_KS)), EDDSA_KS_PASSWORD.toCharArray());
+
+        PrivateKey privateKey =
+                (PrivateKey) keyStore.getKey("Ed25519", EDDSA_KS_PASSWORD.toCharArray());
+
+        doVerify(doSign(privateKey, (X509Certificate) keyStore.getCertificate("Ed25519"), null, XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519));
+    }
+
+    @org.junit.jupiter.api.Test
+    public void testEd22519VerifyXML() throws Exception {
+
+        try (InputStream xmlSignatureExample
+                     = EDDSASignatureTest.class.getResourceAsStream("/org/apache/xml/security/samples/input/eddsaEd25519Signature.xml")) {
+            doVerify(xmlSignatureExample);
+        }
+    }
+
+    @org.junit.jupiter.api.Test
+    public void testEd448VerifyXML() throws Exception {
+
+        try (InputStream xmlSignatureExample
+                     = EDDSASignatureTest.class.getResourceAsStream("/org/apache/xml/security/samples/input/eddsaEd448Signature.xml")) {
+            doVerify(xmlSignatureExample);
+        }
+    }
+
+    @org.junit.jupiter.api.Test
+    public void testEd448() throws Exception {
+
+        KeyStore keyStore = KeyStore.getInstance(EDDSA_KS_TYPE);
+        keyStore.load(Files.newInputStream(Paths.get(EDDSA_KS)), EDDSA_KS_PASSWORD.toCharArray());
+
+        PrivateKey privateKey =
+                (PrivateKey) keyStore.getKey("Ed448", EDDSA_KS_PASSWORD.toCharArray());
+
+        doVerify(doSign(privateKey, (X509Certificate) keyStore.getCertificate("Ed448"), null, XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448));
+    }
+
+
+    private byte[] doSign(PrivateKey privateKey, X509Certificate x509, PublicKey publicKey, String signAlgorithm) throws Exception {
+        org.w3c.dom.Document doc = TestUtils.newDocument();
+        doc.appendChild(doc.createComment(" Comment before "));
+        Element root = doc.createElementNS("", "RootElement");
+
+        doc.appendChild(root);
+        root.appendChild(doc.createTextNode("Some simple text\n"));
+
+        Element canonElem =
+                XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_CANONICALIZATIONMETHOD);
+        canonElem.setAttributeNS(
+                null, Constants._ATT_ALGORITHM, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS
+        );
+
+        SignatureAlgorithm signatureAlgorithm =
+                new SignatureAlgorithm(doc, signAlgorithm);
+        XMLSignature sig =
+                new XMLSignature(doc, null, signatureAlgorithm.getElement(), canonElem);
+
+        root.appendChild(sig.getElement());
+        doc.appendChild(doc.createComment(" Comment after "));
+        Transforms transforms = new Transforms(doc);
+        transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
+        transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
+        sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
+
+        if (x509 != null) {
+            sig.addKeyInfo(x509);
+        } else {
+            sig.addKeyInfo(publicKey);
+        }
+        sig.sign(privateKey);
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+        XMLUtils.outputDOMc14nWithComments(doc, bos);
+        return bos.toByteArray();
+    }
+
+    private void doVerify(byte[] signedXml) throws Exception {
+        try (InputStream is = new ByteArrayInputStream(signedXml)) {
+            doVerify(is);
+        }
+    }
+
+    private void doVerify(InputStream is) throws Exception {
+        org.w3c.dom.Document doc = XMLUtils.read(is, false);
+
+        XPathFactory xpf = XPathFactory.newInstance();
+        XPath xpath = xpf.newXPath();
+        xpath.setNamespaceContext(new DSNamespaceContext());
+
+        String expression = "//ds:Signature[1]";
+        Element sigElement =
+                (Element) xpath.evaluate(expression, doc, XPathConstants.NODE);
+        XMLSignature signature = new XMLSignature(sigElement, "");
+
+        signature.addResourceResolver(new XPointerResourceResolver(sigElement));
+
+        KeyInfo ki = signature.getKeyInfo();
+        if (ki == null) {
+            throw new RuntimeException("No keyinfo");
+        }
+        X509Certificate cert = signature.getKeyInfo().getX509Certificate();
+        if (cert != null) {
+            Assertions.assertTrue(signature.checkSignatureValue(cert));
+        } else {
+            Assertions.assertTrue(signature.checkSignatureValue(signature.getKeyInfo().getPublicKey()));
+        }
+    }
+
+/**
+ * DO NOT DELETE THIS COMMENTED OUT METHOD!
+ *
+ * The reason this method is commented out is to avoid introducing explicit
+ * BouncyCastle dependencies.
+ *
+ * Create an X.509 Certificate and associated private key using the Edwards-Curve Digital Signature Algorithm
+ * DSA algorithm, and store in a KeyStore. This method was used to generate the
+ * keystore used for this test
+ * ("src/test/resources/org/apache/xml/security/samples/input/eddsa.p12").
+ * To generate certificte add the:  org.bouncycastle::bcpkix-jdk18on
+
+ private static void setUpKeyAndCertificate() throws Exception {
+ String[] algorithms = new String []{"Ed25519","Ed448"};
+ KeyStore keyStore = KeyStore.getInstance("PKCS12");
+ keyStore.load(null, EDDSA_KS_PASSWORD.toCharArray());
+ for (String parameterName:algorithms) {
+
+
+ String signatureAlgName = parameterName;
+
+ java.security.KeyPairGenerator kpg =
+ java.security.KeyPairGenerator.getInstance(parameterName, org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME);
+ org.bouncycastle.jcajce.spec.EdDSAParameterSpec keySpec = new org.bouncycastle.jcajce.spec.EdDSAParameterSpec(parameterName);
+ kpg.initialize(keySpec, new java.security.SecureRandom());
+
+ // Cert data
+ java.security.KeyPair keyPair = kpg.generateKeyPair();
+ long now = System.currentTimeMillis();
+ java.util.Date from_date = new java.util.Date(now);
+ java.util.Calendar cal = new java.util.GregorianCalendar();
+ cal.setTime(from_date);
+ cal.add(java.util.Calendar.YEAR, 4);
+ java.util.Date to_date = cal.getTime();
+
+ org.bouncycastle.asn1.x500.X500Name subject = new org.bouncycastle.asn1.x500.X500Name("CN=XML "+parameterName+" Signature Test,DC=apache,DC=org");
+ org.bouncycastle.cert.X509v3CertificateBuilder certBuilder = new org.bouncycastle.cert.X509v3CertificateBuilder(subject,
+ java.math.BigInteger.valueOf(now), from_date, to_date, subject,
+ SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()));
+
+ certBuilder.addExtension(org.bouncycastle.asn1.x509.Extension.basicConstraints, true, new org.bouncycastle.asn1.x509.BasicConstraints(true));
+ certBuilder.addExtension(org.bouncycastle.asn1.x509.Extension.keyUsage, true, new org.bouncycastle.asn1.x509.KeyUsage(org.bouncycastle.asn1.x509.KeyUsage.digitalSignature |
+ org.bouncycastle.asn1.x509.KeyUsage.keyEncipherment |
+ org.bouncycastle.asn1.x509.KeyUsage.keyCertSign |
+ org.bouncycastle.asn1.x509.KeyUsage.cRLSign));
+
+ ContentSigner sigGen = new JcaContentSignerBuilder(signatureAlgName)
+ .build(keyPair.getPrivate());
+
+ X509Certificate x509 = new JcaX509CertificateConverter().getCertificate(certBuilder.build(sigGen));
+
+
+ keyStore.setKeyEntry(
+ parameterName, keyPair.getPrivate(),
+ EDDSA_KS_PASSWORD.toCharArray(), new java.security.cert.Certificate[]{x509}
+ );
+ }
+ keyStore.store(
+ new java.io.FileOutputStream(EDDSA_KS), EDDSA_KS_PASSWORD.toCharArray()
+ );
+ }
+ */
+}
diff --git a/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingInvalidSignatureEd25519.xml b/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingInvalidSignatureEd25519.xml
new file mode 100644
index 00000000..92582c52
--- /dev/null
+++ b/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingInvalidSignatureEd25519.xml
@@ -0,0 +1,31 @@
+<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519"></ds:SignatureMethod>
+<ds:Reference URI="#foo">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
+<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:Transform>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
+<ds:DigestValue>SaRMZuEOPHiUpJrjWfnciQAmhN8=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>
+TMaM9f+TpFf2oIyEpM5piLK2l9eNs7t4YqhwUPavbkfL51Ms7ff2efDpxQ5QBaV9M6RX5qFZg/1y&#xD;
+etXA+dOlDw==
+</ds:SignatureValue>
+<ds:KeyInfo>
+<ds:X509Data>
+<ds:X509Certificate>
+MIIBezCCAS2gAwIBAgIGAYR2SB6KMAUGAytlcDBSMSMwIQYDVQQDDBpYTUwgRWQyNTUxOSBTaWdu&#xD;
+YXR1cmUgVGVzdDEWMBQGCgmSJomT8ixkARkWBmFwYWNoZTETMBEGCgmSJomT8ixkARkWA29yZzAe&#xD;
+Fw0yMjExMTQxMzE1NDhaFw0yNjExMTQxMzE1NDhaMFIxIzAhBgNVBAMMGlhNTCBFZDI1NTE5IFNp&#xD;
+Z25hdHVyZSBUZXN0MRYwFAYKCZImiZPyLGQBGRYGYXBhY2hlMRMwEQYKCZImiZPyLGQBGRYDb3Jn&#xD;
+MCowBQYDK2VwAyEAhxvsjkHukjJDs7Z8NvUNUChup4RKpkfTMPRnseY+SwyjIzAhMA8GA1UdEwEB&#xD;
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGmMAUGAytlcANBALRvL/aEAn9WWtPpseszszSWR3Gyn5IS&#xD;
+qgXKtWbiZIMUTvF7QU8MgkXK8s329fPLCb8+6kvE6K24bxVWpabEEgs=
+</ds:X509Certificate>
+</ds:X509Data>
+</ds:KeyInfo>
+<ds:Object Id="object"><Assertion AssertionID="foo">Some simple text changed after the signature</Assertion></ds:Object></ds:Signature>
diff --git a/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingInvalidSignatureEd448.xml b/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingInvalidSignatureEd448.xml
new file mode 100644
index 00000000..7c6c46d6
--- /dev/null
+++ b/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingInvalidSignatureEd448.xml
@@ -0,0 +1,32 @@
+<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448"></ds:SignatureMethod>
+<ds:Reference URI="#foo">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
+<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:Transform>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
+<ds:DigestValue>SaRMZuEOPHiUpJrjWfnciQAmhN8=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>
+6U+Jj4y/W1S5NBQ++BIaqydoc7RHHkZwFhOJ+xwq9t5PFx4BC2OW71HfWuVgXcEWU5mvDgYRPl2A&#xD;
+qal9fMV2tDOkqadER/ytKn/hQ1/Tq5WEF0TDCQRd3HuerI0XjCZv/AJPfMUuGPBDUSQp4i3CNTIA
+</ds:SignatureValue>
+<ds:KeyInfo>
+<ds:X509Data>
+<ds:X509Certificate>
+MIIBwjCCAUKgAwIBAgIGAYR2SB8kMAUGAytlcTBQMSEwHwYDVQQDDBhYTUwgRWQ0NDggU2lnbmF0&#xD;
+dXJlIFRlc3QxFjAUBgoJkiaJk/IsZAEZFgZhcGFjaGUxEzARBgoJkiaJk/IsZAEZFgNvcmcwHhcN&#xD;
+MjIxMTE0MTMxNTQ4WhcNMjYxMTE0MTMxNTQ4WjBQMSEwHwYDVQQDDBhYTUwgRWQ0NDggU2lnbmF0&#xD;
+dXJlIFRlc3QxFjAUBgoJkiaJk/IsZAEZFgZhcGFjaGUxEzARBgoJkiaJk/IsZAEZFgNvcmcwQzAF&#xD;
+BgMrZXEDOgBSokK9a5+Bpmi4vZkdhdvKDJK6AfR5aBo95bEqrdNGli+s+0iTsVvLptAvSNZu2xQK&#xD;
+88rbOTbGVACjIzAhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGmMAUGAytlcQNzAF2v&#xD;
+bxSz55R+nN3FDZKuu/Yhq/jEfjH9i7aAwB0HSKqqq3RiPKl48F1ER7kYwDJjZYmj0SXdCzqZgFVN&#xD;
+dCb6GgrdFIqxg+DHqfoQ+tM+fvhpkkydTtAvKcUX8xspuQ8C2jv39OzEH2ONzMdtWjjS4H4ZAA==
+</ds:X509Certificate>
+</ds:X509Data>
+</ds:KeyInfo>
+<ds:Object Id="object"><Assertion AssertionID="foo">Some simple text changed after the signature</Assertion></ds:Object></ds:Signature>
diff --git a/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingSignatureEd25519.xml b/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingSignatureEd25519.xml
new file mode 100644
index 00000000..cd10795a
--- /dev/null
+++ b/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingSignatureEd25519.xml
@@ -0,0 +1,31 @@
+<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519"></ds:SignatureMethod>
+<ds:Reference URI="#foo">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
+<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:Transform>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
+<ds:DigestValue>SaRMZuEOPHiUpJrjWfnciQAmhN8=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>
+TMaM9f+TpFf2oIyEpM5piLK2l9eNs7t4YqhwUPavbkfL51Ms7ff2efDpxQ5QBaV9M6RX5qFZg/1y&#xD;
+etXA+dOlDw==
+</ds:SignatureValue>
+<ds:KeyInfo>
+<ds:X509Data>
+<ds:X509Certificate>
+MIIBezCCAS2gAwIBAgIGAYR2SB6KMAUGAytlcDBSMSMwIQYDVQQDDBpYTUwgRWQyNTUxOSBTaWdu&#xD;
+YXR1cmUgVGVzdDEWMBQGCgmSJomT8ixkARkWBmFwYWNoZTETMBEGCgmSJomT8ixkARkWA29yZzAe&#xD;
+Fw0yMjExMTQxMzE1NDhaFw0yNjExMTQxMzE1NDhaMFIxIzAhBgNVBAMMGlhNTCBFZDI1NTE5IFNp&#xD;
+Z25hdHVyZSBUZXN0MRYwFAYKCZImiZPyLGQBGRYGYXBhY2hlMRMwEQYKCZImiZPyLGQBGRYDb3Jn&#xD;
+MCowBQYDK2VwAyEAhxvsjkHukjJDs7Z8NvUNUChup4RKpkfTMPRnseY+SwyjIzAhMA8GA1UdEwEB&#xD;
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGmMAUGAytlcANBALRvL/aEAn9WWtPpseszszSWR3Gyn5IS&#xD;
+qgXKtWbiZIMUTvF7QU8MgkXK8s329fPLCb8+6kvE6K24bxVWpabEEgs=
+</ds:X509Certificate>
+</ds:X509Data>
+</ds:KeyInfo>
+<ds:Object Id="object"><Assertion AssertionID="foo">Some simple text</Assertion></ds:Object></ds:Signature>
\ No newline at end of file
diff --git a/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingSignatureEd448.xml b/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingSignatureEd448.xml
new file mode 100644
index 00000000..d5f6486e
--- /dev/null
+++ b/src/test/resources/javax/xml/crypto/dsig/eddsa/envelopingSignatureEd448.xml
@@ -0,0 +1,32 @@
+<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448"></ds:SignatureMethod>
+<ds:Reference URI="#foo">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
+<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:Transform>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
+<ds:DigestValue>SaRMZuEOPHiUpJrjWfnciQAmhN8=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>
+6U+Jj4y/W1S5NBQ++BIaqydoc7RHHkZwFhOJ+xwq9t5PFx4BC2OW71HfWuVgXcEWU5mvDgYRPl2A&#xD;
+qal9fMV2tDOkqadER/ytKn/hQ1/Tq5WEF0TDCQRd3HuerI0XjCZv/AJPfMUuGPBDUSQp4i3CNTIA
+</ds:SignatureValue>
+<ds:KeyInfo>
+<ds:X509Data>
+<ds:X509Certificate>
+MIIBwjCCAUKgAwIBAgIGAYR2SB8kMAUGAytlcTBQMSEwHwYDVQQDDBhYTUwgRWQ0NDggU2lnbmF0&#xD;
+dXJlIFRlc3QxFjAUBgoJkiaJk/IsZAEZFgZhcGFjaGUxEzARBgoJkiaJk/IsZAEZFgNvcmcwHhcN&#xD;
+MjIxMTE0MTMxNTQ4WhcNMjYxMTE0MTMxNTQ4WjBQMSEwHwYDVQQDDBhYTUwgRWQ0NDggU2lnbmF0&#xD;
+dXJlIFRlc3QxFjAUBgoJkiaJk/IsZAEZFgZhcGFjaGUxEzARBgoJkiaJk/IsZAEZFgNvcmcwQzAF&#xD;
+BgMrZXEDOgBSokK9a5+Bpmi4vZkdhdvKDJK6AfR5aBo95bEqrdNGli+s+0iTsVvLptAvSNZu2xQK&#xD;
+88rbOTbGVACjIzAhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGmMAUGAytlcQNzAF2v&#xD;
+bxSz55R+nN3FDZKuu/Yhq/jEfjH9i7aAwB0HSKqqq3RiPKl48F1ER7kYwDJjZYmj0SXdCzqZgFVN&#xD;
+dCb6GgrdFIqxg+DHqfoQ+tM+fvhpkkydTtAvKcUX8xspuQ8C2jv39OzEH2ONzMdtWjjS4H4ZAA==
+</ds:X509Certificate>
+</ds:X509Data>
+</ds:KeyInfo>
+<ds:Object Id="object"><Assertion AssertionID="foo">Some simple text</Assertion></ds:Object></ds:Signature>
\ No newline at end of file
diff --git a/src/test/resources/org/apache/xml/security/samples/input/eddsa.p12 b/src/test/resources/org/apache/xml/security/samples/input/eddsa.p12
new file mode 100644
index 00000000..aaf3b2f2
Binary files /dev/null and b/src/test/resources/org/apache/xml/security/samples/input/eddsa.p12 differ
diff --git a/src/test/resources/org/apache/xml/security/samples/input/eddsaEd25519Signature.xml b/src/test/resources/org/apache/xml/security/samples/input/eddsaEd25519Signature.xml
new file mode 100644
index 00000000..e67158d7
--- /dev/null
+++ b/src/test/resources/org/apache/xml/security/samples/input/eddsaEd25519Signature.xml
@@ -0,0 +1,34 @@
+<!-- Comment before -->
+<RootElement>Some simple text
+<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519"></ds:SignatureMethod>
+<ds:Reference URI="">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
+<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:Transform>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
+<ds:DigestValue>LKyUpNaZJ2joznVzwEup5JDwtS0=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>
+V4fnFoXxWJEJpSr/MnkmAOF5iM/OGeg/f/Vkw+aD+R1BsPZr5voeUKr0Et29WLv51numcRJ9coED&#xD;
+iQXcoIbLAg==
+</ds:SignatureValue>
+<ds:KeyInfo>
+<ds:X509Data>
+<ds:X509Certificate>
+MIIBezCCAS2gAwIBAgIGAYR2SB6KMAUGAytlcDBSMSMwIQYDVQQDDBpYTUwgRWQyNTUxOSBTaWdu&#xD;
+YXR1cmUgVGVzdDEWMBQGCgmSJomT8ixkARkWBmFwYWNoZTETMBEGCgmSJomT8ixkARkWA29yZzAe&#xD;
+Fw0yMjExMTQxMzE1NDhaFw0yNjExMTQxMzE1NDhaMFIxIzAhBgNVBAMMGlhNTCBFZDI1NTE5IFNp&#xD;
+Z25hdHVyZSBUZXN0MRYwFAYKCZImiZPyLGQBGRYGYXBhY2hlMRMwEQYKCZImiZPyLGQBGRYDb3Jn&#xD;
+MCowBQYDK2VwAyEAhxvsjkHukjJDs7Z8NvUNUChup4RKpkfTMPRnseY+SwyjIzAhMA8GA1UdEwEB&#xD;
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGmMAUGAytlcANBALRvL/aEAn9WWtPpseszszSWR3Gyn5IS&#xD;
+qgXKtWbiZIMUTvF7QU8MgkXK8s329fPLCb8+6kvE6K24bxVWpabEEgs=
+</ds:X509Certificate>
+</ds:X509Data>
+</ds:KeyInfo>
+</ds:Signature></RootElement>
+<!-- Comment after -->
\ No newline at end of file
diff --git a/src/test/resources/org/apache/xml/security/samples/input/eddsaEd448Signature.xml b/src/test/resources/org/apache/xml/security/samples/input/eddsaEd448Signature.xml
new file mode 100644
index 00000000..f4d9c6d0
--- /dev/null
+++ b/src/test/resources/org/apache/xml/security/samples/input/eddsaEd448Signature.xml
@@ -0,0 +1,35 @@
+<!-- Comment before -->
+<RootElement>Some simple text
+<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448"></ds:SignatureMethod>
+<ds:Reference URI="">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
+<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:Transform>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
+<ds:DigestValue>LKyUpNaZJ2joznVzwEup5JDwtS0=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>
+akkDnnKP8IH2lupCxXPW/l+s/L259MUgd3hTjFY9tg9SUlcQhyG48mZvZh6eh870IvFy/0z30hYA&#xD;
+HDXW5ZuqvgrF4voKqBrs9WWsIwXMXTUWhzelrEaL4PGgGmeNfi9d+r9lsNtpuhCg7c9nAU4wTjUA
+</ds:SignatureValue>
+<ds:KeyInfo>
+<ds:X509Data>
+<ds:X509Certificate>
+MIIBwjCCAUKgAwIBAgIGAYR2SB8kMAUGAytlcTBQMSEwHwYDVQQDDBhYTUwgRWQ0NDggU2lnbmF0&#xD;
+dXJlIFRlc3QxFjAUBgoJkiaJk/IsZAEZFgZhcGFjaGUxEzARBgoJkiaJk/IsZAEZFgNvcmcwHhcN&#xD;
+MjIxMTE0MTMxNTQ4WhcNMjYxMTE0MTMxNTQ4WjBQMSEwHwYDVQQDDBhYTUwgRWQ0NDggU2lnbmF0&#xD;
+dXJlIFRlc3QxFjAUBgoJkiaJk/IsZAEZFgZhcGFjaGUxEzARBgoJkiaJk/IsZAEZFgNvcmcwQzAF&#xD;
+BgMrZXEDOgBSokK9a5+Bpmi4vZkdhdvKDJK6AfR5aBo95bEqrdNGli+s+0iTsVvLptAvSNZu2xQK&#xD;
+88rbOTbGVACjIzAhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGmMAUGAytlcQNzAF2v&#xD;
+bxSz55R+nN3FDZKuu/Yhq/jEfjH9i7aAwB0HSKqqq3RiPKl48F1ER7kYwDJjZYmj0SXdCzqZgFVN&#xD;
+dCb6GgrdFIqxg+DHqfoQ+tM+fvhpkkydTtAvKcUX8xspuQ8C2jv39OzEH2ONzMdtWjjS4H4ZAA==
+</ds:X509Certificate>
+</ds:X509Data>
+</ds:KeyInfo>
+</ds:Signature></RootElement>
+<!-- Comment after -->
\ No newline at end of file