[Mono-dev] [PATCH] Set hash algorithms block size

Javier Mart� lordhabbit at gmail.com
Thu Nov 29 07:10:14 EST 2007

In all Mono implementations (up to tonight's SVN) of the hash algorithms in
[corlib]System.Security.Cryptography, all of them fail to override the
InputBlockSize and OutputBlockSize properties, leaving them at 1 byte.

This should be mainly harmless, but, combined another bug in CryptoStream which
makes it ignore the CanTransformMultipleBlocks property of its ICryptoTransform
when reading (though not when writing!, brings about this doomsday scenario:
reading a 3MB file through a CryptoStream of, say, SHA1, issues about 3 million
calls to Buffer.BlockCopy and the same number to HashAlgorithm.TransformBlock.
That is, CryptoStream and HashAlgorithm are having fun passing millions of
one-byte arrays between them (and copying them). The speed penalty is extreme,
as stated below.

This fix is twofold: to begin with, I've modified the abstract base classes of
all hash algorithms in Sys.Sec.Crypto to include a protected const field called
SPEC_BLOKCSIZE and overriden InputBlockSize and OutputBlockSize to return this
value. In principle, it should be cleaner to just add them to implementations
(SHA1Managed instead of SHA1), but the default provided is the one given by the
spec defining the algorithm, so most (sane) implementations are going to use it
and those who don't because they compute the hash through some other equivalent
method can just override the properties again.

The results are self-evident: even with the bug in CryptoStream (which I'll try
to patch shortly), the 3M calls turn into about 50K (3M / 64) in SHA1 or 25K
(3M / 128) in SHA2-512. In terms of time, hashing that 3MB file through CS went
down from 2.5s to about 0.5s. Thus, the speedup achieved was about 500%!

The (upcoming) second patch should reduce this number even more in algorithms
supporting CanTransformMultipleBlocks, so the number of calls to TransformBlock
(and thus buffer allocs & copies) would be divided by the size passed to Read.

PD: I'm the "stalker" studend from yesterday Summit session. Sorry I won't be
    able to attend the rest of the sessions: Boo looked interesting.
PD2: It's the first time I send a formal diff patch to a project, so sorry if
     I missed some format rule - though I tried to replicate the formatting of
     code around my additions. Also, I've compiled the code (no Ws/Es) and
     lightly tested it hashing some files. It _seems_ I didn't break anything,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: blocksizes.diff
Type: text/x-patch
Size: 4597 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20071129/00cd90bc/attachment.bin 

More information about the Mono-devel-list mailing list