feat: introduce hybrid signature framework and signature trailer builder

Add a complete hybrid signature implementation combining two independent
signature algorithms with AND/OR verification semantics, designed for
streaming pipelines.

Key changes:
- Add zeroecho.sdk.hybrid.signature package with core hybrid signature
  abstractions (HybridSignatureContext, HybridSignatureProfile,
  factories, predicates, and package documentation).
- Introduce SignatureTrailerDataContentBuilder as a
  signature-specialized replacement for
  TagTrailerDataContentBuilder<Signature>, supporting
  core, single-algorithm, and hybrid signature construction.
- Extend sdk.builders package documentation to reference the new
  signature trailer builder and newly added PQC signature builders.
- Adjust TagEngineBuilder where required to support hybrid verification
  integration.
- Update JUL configuration to accommodate hybrid signature diagnostics
  without leaking sensitive material.

Tests and samples:
- Add comprehensive JUnit 5 tests covering hybrid signatures in all
  supported modes, including positive and negative cases.
- Add a dedicated sample demonstrating hybrid signing combined with AES
  encryption (StE and EtS).
- Update existing signing samples to reflect the new signature trailer
  builder.

The changes introduce a unified, extensible hybrid signature model
without breaking existing core APIs or pipeline composition patterns.

Signed-off-by: Leo Galambos <lg@hq.egothor.org>
This commit is contained in:
2025-12-26 02:01:29 +01:00
parent 174d63dff4
commit 7f79082adc
14 changed files with 2756 additions and 31 deletions

View File

@@ -48,9 +48,7 @@ import javax.crypto.SecretKey;
import org.junit.jupiter.api.Test;
import zeroecho.core.CryptoAlgorithm;
import zeroecho.core.CryptoAlgorithms;
import zeroecho.core.alg.aes.AesKeyGenSpec;
import zeroecho.core.alg.rsa.RsaKeyGenSpec;
import zeroecho.core.alg.rsa.RsaSigSpec;
import zeroecho.core.tag.TagEngine;
@@ -65,23 +63,6 @@ import zeroecho.sdk.content.api.DataContent;
class SigningAesTest {
private static final Logger LOG = Logger.getLogger(SigningAesTest.class.getName());
SecretKey generateAesKey() throws GeneralSecurityException {
// Locate the AES algorithm in the catalog
CryptoAlgorithm aes = CryptoAlgorithms.require("AES");
SecretKey key = aes
// Retrieve the builder that works with AesKeyGenSpec - the specification for
// AES key generation
.symmetricKeyBuilder(AesKeyGenSpec.class)
// Generate a secret key according to the AES256 specification
.generateSecret(AesKeyGenSpec.aes256());
// Log the generated key (truncated to short hex for readability)
LOG.log(Level.INFO, "AES256 key generated: {0}", Strings.toShortHexString(key.getEncoded()));
// or just: CryptoAlgorithms.generateSecret("AES", AesKeyGenSpec.aes256())
return key;
}
KeyPair generateRsaKeys() throws GeneralSecurityException {
KeyPair kp = CryptoAlgorithms.generateKeyPair("RSA", RsaKeyGenSpec.rsa4096());