Package zeroecho.core.io


package zeroecho.core.io
I/O helpers for block-based transforms, passthrough processing, and tail handling.

This package provides building blocks for cryptographic I/O: chunk-transforming streams that call into a cipher, passthrough streams that compute or append trailers, a builder for configuring cipher-backed streams, a tail-stripping stream, and small I/O utilities. Components are designed to be allocation-conscious and to make finalization output (padding blocks, AEAD tags) explicit and predictable.

Key elements

  • AbstractChunkTransformInputStream - base class that reads upstream data in aligned chunks and lets subclasses implement transform(...) and doFinal(...).
  • AbstractPassthroughInputStream - forwards body bytes unchanged, invokes update(...) on each chunk, optionally emits a single trailer, then calls onCompleted() exactly once at EOF.
  • CipherTransformInputStreamBuilder - fluent builder that creates cipher-backed streams for block-per-doFinal, left-zero-padded blocks, or continuous update+doFinal streaming.
  • SmartBlockStream, SmartPaddedBlockStream, SmartContinuousBlockStream - concrete cipher-backed stream variants used by the builder.
  • TailStrippingInputStream - withholds the last N bytes from the payload and delivers them to a callback at EOF (useful for tags, checksums, or footers).
  • Util - static helpers for compact length-prefix I/O, UTF-8, UUID, and packed 7-bit integers.

Typical usage

Build a streaming AES/GCM transform


 javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/GCM/NOPADDING");
 javax.crypto.spec.GCMParameterSpec gcm = new javax.crypto.spec.GCMParameterSpec(128, ivBytes);
 cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, aesKey, gcm);

 java.io.InputStream s = zeroecho.core.io.CipherTransformInputStreamBuilder.builder()
     .withUpstream(upstream)
     .withCipher(cipher)
     .withUpdateStreaming()          // use update(...) for bulk, doFinal() at EOF
     .withInputBlockSize(16)         // logical chunking for I/O
     .withOutputBlockSize(16)
     .withBufferedBlocks(200)        // steady-state buffering
     .withFinalizationOutputChunks(2) // room for tail bytes + 16-byte tag
     .build();

 // Pipe transformed bytes
 s.transferTo(out);
 s.close();
 

Strip a fixed trailer (for example, 16-byte tag) from the end of a stream


 int tagLen = 16;
 zeroecho.core.io.TailStrippingInputStream in =
     new zeroecho.core.io.TailStrippingInputStream(raw, tagLen, 4096) {
         @Override
         protected void processTail(byte[] tail) throws java.io.IOException {
             // verify MAC, parse footer, etc. (do not write to 'out' here)
         }
     };

 // Read payload only; the last 'tagLen' bytes are withheld and delivered to processTail(...)
 byte[] payload = in.readAllBytes();
 in.close(); // ensures processTail(...) runs even if not fully consumed
 

Design notes

  • Streams are not thread-safe; use one instance per pipeline.
  • Finalization headroom is explicit: reserve extra output chunks when a mode emits padding or tags at EOF.
  • close() implementations drain upstream as needed to guarantee trailer emission and completion hooks.
Since:
1.0