Closed
Description
In a number of protocols signing is based on a hash of all messages up to the signing point in the protocol. Incremental Hash is great for that because it means we don't need to hold all the current messages in the conversation in memory. However if we are required to sign at a specific point but then continue hashing for a future signing point we are stuck as we can only do a FinishAndReset
My proposal is to add a Clone or Duplicate method
public partial class IncrementalHash
{
// Returns a new IncrementalHash in the same state
public IncrementalHash DuplicateHash() => throw null;
// Gets the completed hash for the already applied values,
// but does not block AppendData from accepting more data.
// These produce equivalent (hash1, hash2) values:
// A)
// hasher.AppendData(data1);
// byte[] hash1 = hasher.GetCurrentHash();
// hasher.AppendData(data2);
// byte[] hash2 = hasher.GetCurrentHash();
// B)
// hasher.AppendData(data1);
// byte[] hash1 = hasher.GetHashAndReset();
// hasher.AppendData(data1);
// hasher.AppendData(data2);
// byte[] hash2 = hasher.GetHashAndReset();
// C)
// hasher.AppendData(data1);
// using (IncrementalHash tmp = hasher.DuplicateHash())
// {
// hash1 = tmp.GetHashAndReset();
// }
// hasher.AppendData(data2);
// hash2 = hasher.GetHashAndReset();
public bool TryGetCurrentHash(Span<byte> destination, out int bytesWritten) => throw null;
public byte[] GetCurrentHash() => throw null;
}
I know for a fact that both OpenSsl and BCrypt support this operation, I am unsure on osx.
Such implementation on OpenSsl would look like
var ctx = EVP_MD_CTX_copy_ex(_ctx);
And in BCrypt something like
var newHash = BCryptDuplicateHash(_hashHandle);
Obviously with differences due to using the .net core PAL etc
- Updated to put back the (Try) GetCurrentHash methods as suggested by @bartonjs