EasyPQC.FileOperations
Types
PackedFile
Represents a packed (compressed + optionally encrypted) file along with its cryptographic signature.
- Fields:
- string FilePath – Full path of the resulting packed file.
- byte[] Signature – Blake3 hash of the original file (signed or raw depending on use case).
- Methods:
- override string ToString() → Returns "FilePath|Signature(Base64)"
- static PackedFile FromString(string packedFileString) – Parses a string in the above format back into a PackedFile instance.
CompressionLevel (enum)
Controls trade-off between speed and compression ratio when using LZ4.
- Fast – Prioritizes speed (default LZ4 fast mode)
- Balanced – Good ratio with reasonable speed
- Max – Highest compression (uses LZ4 HC)
CompressionProgress (delegate)
public delegate void CompressionProgress(long current, long total, int percentage);
Callback used to report real-time progress during compression/decompression.
Methods
CompressFileAsync
Task<string> CompressFileAsync(
string fileInput,
string fileOutput,
CompressionProgress progress = null,
CompressionLevel level = CompressionLevel.Fast)
Asynchronously compresses a file using LZ4/LZ4HC. Returns the path to the compressed file (.lz4 extension added if not present).
DecompressFileAsync
Task<string> DecompressFileAsync(
string fileInput,
string fileOutput,
CompressionProgress progress = null,
CompressionLevel level = CompressionLevel.Fast)
Asynchronously decompresses an LZ4-compressed file. Returns the path to the decompressed output file.
HashFile
public static async Task<byte[]> HashFile(Stream fileData)
Computes the Blake3 hash of a file/stream entirely in memory. Suitable for files that fit in RAM or when streaming through a MemoryStream.
Current Implementation (Working):
public static async Task<byte[]> HashFile(Stream fileData)
{
return await Task.Run(() =>
{
fileData.Seek(0, SeekOrigin.Begin);
var hasher = Blake3.Hasher.New(); // Using Blake3.Net
var buffer = new byte[81920];
int bytesRead;
while ((bytesRead = fileData.Read(buffer, 0, buffer.Length)) > 0)
hasher.Update(buffer.AsSpan(0, bytesRead));
return hasher.Finalize().ToArray();
});
}
Note: The old MemoryStream copy version has been replaced with proper streaming to support large files without OOM.
VerifyHash
public static async Task<bool> VerifyHash(Stream fileData, byte[] expectedSignature)
Re-computes the Blake3 hash of the stream and compares it against the expected signature.
public static async Task<bool> VerifyHash(Stream fileData, byte[] expectedSignature)
{
var computed = await HashFile(fileData);
return computed.SequenceEqual(expectedSignature);
}
PackFiles (Signature + Optional Encryption)
Task<PackedFile> PackFiles(
string fileInput,
string outputDirectory,
byte[] privateKey, // For signing hash (Ed25519/Curve25519+X)
SecureData sessionKey = null, // Optional AES-256-GCM session key
CompressionProgress progress = null,
CompressionLevel level = CompressionLevel.Balanced,
bool encrypt = true)
Full packing pipeline:
- Compress file with LZ4
- Compute Blake3 hash of original file
- (Optional) Sign hash with privateKey
- (Optional) Encrypt compressed data + signature with sessionKey
- Write final packed file
- Return PackedFile with path and final signature
UnpackFile (Verify + Decrypt + Decompress)
Task<bool> UnpackFile(
PackedFile packedFile,
string outputPath,
byte[] publicKey, // To verify signature
CompressionProgress progress = null,
CompressionLevel level = CompressionLevel.Balanced,
SecureData sessionKey = null)
Reverse operation:
- Decrypt if encrypted
- Verify Blake3 ± signature using public key
- Decompress with LZ4
- Write original file
Returns true on success and integrity verified.