Description
Background and motivation
There has been some interest in making IncrementalHash
clone-able, in the sense that cloning it duplicates the state of the hash. That was originally proposed in #1968, however at the time it was believed that a "give me the current hash" was sufficient, and we could add Clone
later if it still seemed useful.
Some feedback has shown that it would be useful to be able to snapshot and rewind an IncrementalHash
, such as accumulating file transfer chunks, and if a chunk fails, go back to the last known good chunk and re-download the chunk.
Shake128
and Shake256
also introduced a Clone
, so we have precedent for the name and API.
KMAC would be the only hash/mac primitive that does not have Clone, so we should consider adding it for consistency.
API Proposal
namespace System.Security.Cryptography;
public partial class IncrementalHash {
public IncrementalHash Clone();
}
public partial class Kmac128 {
public Kmac128 Clone();
}
public partial class KmacXof128 {
public KmacXof128 Clone();
}
public partial class Kmac256 {
public Kmac256 Clone();
}
public partial class KmacXof256 {
public KmacXof256 Clone();
}
API Usage
using IncrementalHash ih = new(HashAlgorithmName.SHA256);
ih.AppendData("potato"u8);
using IncrementalHash clone = ih.Clone();
ih.AppendData("tomatoes"u8);
// clone does not have tomatoes appended to it.
Alternative Designs
I had considered if the HashAlgorithm
derived types should implement a Clone
but decided against it for a few reasons.
- It would need to be
virtual
and by default it would need to throw since we don't know how to duplicate arbitrary hash algorithms. - Personally, I consider
HashAlgorithm
"done" and we should not innovate in its API surface. API innovation should either be in the static one-shots,IncrementalHash
, or non-HashAlgorithm derived types that are sealed, likeShake128
andKmac128
, etc. If developers want aClone
for their ownHashAlgorithm
derived types, they are free to add them.
Risks
No response