Package zeroecho.core.alg.common.sig
package zeroecho.core.alg.common.sig
Streaming signature contexts and helpers that adapt JCA
Signature to a pull-based pipeline.
This package provides a generic signature context that wraps an
InputStream, updates a JCA engine as bytes flow, and either
appends a fixed-length trailer (sign) or verifies against a caller-supplied
tag (verify). A small internal passthrough stream performs byte forwarding
and end-of-stream finalization.
Design goals
- Single-use pipeline integration: create a context for SIGN or
VERIFY and call
wrap(InputStream)once. - Known tag length up front: produced/expected signature length is resolved at construction so downstream components can append or strip trailers without buffering the whole stream.
- Provider encapsulation: JCA provider details are hidden behind factories that create initialized engines.
Components
- GenericJcaSignatureContext - streaming context that uses a
configured
Signature, resolves a fixed tag length (via resolvers), and exposes a one-shotwrap(InputStream)API. Verification behavior is controlled by a pluggable comparison approach. - SignatureStream - internal passthrough input stream that feeds chunks to the signature engine, emits the trailer in SIGN mode, and performs final verification in VERIFY mode.
Length resolution
Tag length is determined by resolvers supplied at construction time:
- SignLengthResolver - returns the produced length (fixed or by probing a provider with an empty-message sign).
- VerifyLengthResolver - returns the expected length (fixed or derived from key parameters).
Verification approach
Verification is delegated to a VerificationBiPredicate strategy. The
default core delegates to Signature.verify(byte[]), and
callers may decorate it to throw on mismatch or to record results externally.
Usage sketch
Sign
GenericJcaSignatureContext ctx = new GenericJcaSignatureContext(
algorithm,
privateKey,
GenericJcaSignatureContext.jcaFactory("SHA256withRSA", null),
GenericJcaSignatureContext.SignLengthResolver.probeWith("SHA256withRSA", null));
try (InputStream in = ctx.wrap(upstream)) {
in.transferTo(out); // body, then signature trailer of ctx.tagLength() bytes
}
Verify
GenericJcaSignatureContext vctx = new GenericJcaSignatureContext(
algorithm,
publicKey,
GenericJcaSignatureContext.jcaFactory("SHA256withRSA", null),
GenericJcaSignatureContext.VerifyLengthResolver.fixed(256));
vctx.setVerificationApproach(vctx.getVerificationCore().getThrowOnMismatch());
vctx.setExpectedTag(signatureBytes);
try (InputStream verified = vctx.wrap(bodyWithoutTrailer)) {
verified.transferTo(java.io.OutputStream.nullOutputStream()); // throws on mismatch at EOF
}
Thread-safety
- Contexts and streams are stateful, not thread-safe, and intended for single use.
- Create a new context per wrapped stream.
- Since:
- 1.0
-
ClassDescriptionFactory of initialized
Signatureengines.Strategy for determining the signature trailer length in SIGN mode.Strategy for determining the expected signature length in VERIFY mode.Describes how a standard signature algorithm identifier maps to a concrete ZeroEcho signature context.Signature byte representation bridging policy.Resolves standard signature algorithm identifiers to explicit ZeroEcho signature profiles.Fail-closed containment for stateful signing until durable leaf reservation is available.