GHash128.cs

Generic 128-Bit Hash

using System;
using System.Security.Cryptography;
public class GHash128 : HashAlgorithm
{
    private readonly Int128[] table = new Int128[256];
    private          Int128   hash;
    private          Int128   k    = new Int128("129143687381477724263020268747464783");
    private          Int128   seed = new Int128("5967883051065466352865241413511");
    public GHash128()
    {
        hash     = seed;
        table[0] = k;
        Expand(table);
    }
    public override int HashSize => 128;
    public void SetSeed(Int128 s, Int128 k)
    {
        seed   = s;
        this.k = k;
        Array.Clear(table, 0, table.Length);
        table[0] = this.k;
        Expand(table);
    }
    private static void Expand(Int128[] x)
    {
        var length = x.Length;
        for (var i = 0; i < length; ++i)
        {
            Int128 n = 0;
            for (var j = 0; j < length; ++j)
                n = n ^ x[j];
            x[i] = (n << 1) | (n >> 120) | 1;
        }
    }
    public override void Initialize()
    {
        hash = seed;
    }
    protected override void HashCore(byte[] bytes, int ibStart, int cbSize)
    {
        Transform128(bytes, ibStart, cbSize);
    }
    protected override byte[] HashFinal()
    {
        return hash.ToByteArray();
    }
    public void Transform128(byte[] bytes, int ibStart, int cbSize)
    {
        if (bytes == null)
            return;
        if (ibStart >= bytes.Length || cbSize > bytes.Length)
            return;
        var i = 0;
        do
        {
            hash = (hash ^ bytes[i]) * table[bytes[i++]];
        } while (i < cbSize);
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *