Skip to content

TransformBlock() behaves incorrectly when input data length is not a multiple of 16 #10

@itai

Description

@itai

When the length of the input data is not a multiple of 16, TransformBlock() does not behave correctly. In the following example, the same hash is generated for different byte sequences:

using System.Security.Cryptography;
using System.Text;
using Murmur;

{
    using HashAlgorithm hashAlgorithm = MurmurHash.Create128(preference: AlgorithmPreference.X64);
    TransformSingleByte(hashAlgorithm, 1);
    TransformSingleByte(hashAlgorithm, 1);
    TransformSingleByte(hashAlgorithm, 1);
    TransformSingleByte(hashAlgorithm, 1);
    hashAlgorithm.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
    PrintBytes(hashAlgorithm.Hash!);
}

{
    using HashAlgorithm hashAlgorithm = MurmurHash.Create128(preference: AlgorithmPreference.X64);
    TransformSingleByte(hashAlgorithm, 0);
    TransformSingleByte(hashAlgorithm, 0);
    TransformSingleByte(hashAlgorithm, 0);
    TransformSingleByte(hashAlgorithm, 0);
    hashAlgorithm.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
    PrintBytes(hashAlgorithm.Hash!);
}

{
    using HashAlgorithm hashAlgorithm = MurmurHash.Create128(preference: AlgorithmPreference.X64);
    TransformSingleByte(hashAlgorithm, 0);
    TransformSingleByte(hashAlgorithm, 0);
    TransformSingleByte(hashAlgorithm, 1);
    TransformSingleByte(hashAlgorithm, 1);
    hashAlgorithm.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
    PrintBytes(hashAlgorithm.Hash!);
}

{
    using HashAlgorithm hashAlgorithm = MurmurHash.Create128(preference: AlgorithmPreference.X64);
    TransformSingleByte(hashAlgorithm, 0);
    TransformSingleByte(hashAlgorithm, 1);
    TransformSingleByte(hashAlgorithm, 0);
    TransformSingleByte(hashAlgorithm, 1);
    hashAlgorithm.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
    PrintBytes(hashAlgorithm.Hash!);
}

static void TransformSingleByte(
    HashAlgorithm hashAlgorithm,
    byte @byte) =>
    hashAlgorithm.TransformBlock(new[] {@byte}, 0, 1, null, 0);

static void PrintBytes(IEnumerable<byte> bytes)
{
    var stringBuilder = new StringBuilder();
    foreach (var @byte in bytes)
    {
        stringBuilder.AppendFormat("{0:X2}", @byte);
    }
    Console.WriteLine(stringBuilder.ToString());
}

Output:

BC764CD8DDF7A0CFF126F51C16239658
BC764CD8DDF7A0CFF126F51C16239658
BC764CD8DDF7A0CFF126F51C16239658
BC764CD8DDF7A0CFF126F51C16239658

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions