Want to Join Us ?

you'll be able to discuss, share and send private messages.

OMac - CMac Hash

Discussion in 'C#' started by BuC, Mar 3, 2013.

Share This Page

  1. BuC

    New Member

    • BuC
    • Feb 9, 2013
    • 2
    • 3
    Code (C):
    using System;
    using System.Security.Cryptography;
     
    namespace FreeeeeDat
    {
        public enum OMACVariant
        {
            OMAC1,
            OMAC2
        }
     
        public class OMAC : KeyedHashAlgorithm
        {
            private SymmetricAlgorithm _algorithm;
            private ICryptoTransform _cipher;
            private readonly OMACVariant _variant;
     
            public OMACVariant Variant { get { return _variant; } }
     
            private byte[] _buffer;
            private int _bufferPosition;
     
            private byte[] _lu1;
            private byte[] _lu2;
     
            public OMAC()
                : this(Rijndael.Create(), OMACVariant.OMAC1, null)
            {
            }
     
            public OMAC(SymmetricAlgorithm algorithm, OMACVariant variant)
                : this(algorithm, variant, null)
            {
            }
     
            public OMAC(SymmetricAlgorithm algorithm, OMACVariant variant, byte[] key)
            {
                if (algorithm == null)
                    throw new ArgumentNullException("algorithm");
                if (algorithm.BlockSize != 64 && algorithm.BlockSize != 128)
                    throw new ArgumentException("Unsupported block size");
                if (variant != OMACVariant.OMAC1 && variant != OMACVariant.OMAC2)
                    throw new ArgumentException("Invalid OMAC variant");
     
                _algorithm = algorithm;
                _variant = variant;
     
                _buffer = new byte[algorithm.BlockSize / 8];
                _lu1 = new byte[algorithm.BlockSize / 8];
                _lu2 = new byte[algorithm.BlockSize / 8];
     
                HashSizeValue = algorithm.BlockSize;
     
                if (key == null)
                    KeyValue = algorithm.Key;
                else
                    Key = key;
            }
     
            public override byte[] Key
            {
                set
                {
                    if (!_algorithm.ValidKeySize(value.Length * 8))
                        throw new ArgumentException("Invalid key size");
     
                    base.Key = value;
     
                    if (_cipher != null)
                    {
                        _cipher.Dispose();
                        _cipher = null;
                    }
                }
            }
     
            private void CreateCipher()
            {
                _algorithm.BlockSize = HashSizeValue;
                _algorithm.Mode = CipherMode.ECB;
                _algorithm.Padding = PaddingMode.None;
     
                _cipher = _algorithm.CreateEncryptor(KeyValue, null);
     
     
                _cipher.TransformBlock(_buffer, 0, _buffer.Length, _buffer, 0);
     
                ApplyU(_buffer, _lu1);
     
                if (_variant == OMACVariant.OMAC1)
                    ApplyU(_lu1, _lu2);
                else
                    ApplyInverseU(_buffer, _lu2);
     
     
                Array.Clear(_buffer, 0, _buffer.Length);
            }
     
            private void ApplyU(byte[] source, byte[] dest)
            {
                for (int i = 0; ; )
                {
                    dest[i] = (byte)(source[i] << 1);
     
                    if (++i >= source.Length)
                        break;
     
                    if ((source[i] & 0x80) != 0)
                        dest[i - 1] |= 0x1;
                }
     
                if ((source[0] & 0x80) != 0)
                {
                    if (dest.Length == 8)
                        dest[7] ^= 0x1B;
                    else
                        dest[15] ^= 0x87;
                }
            }
     
            private void ApplyInverseU(byte[] source, byte[] dest)
            {
                for (int i = source.Length - 1; ; )
                {
                    dest[i] = (byte)(source[i] >> 1);
     
                    if (--i < 0)
                        break;
     
                    if ((source[i] & 0x01) != 0)
                        dest[i + 1] |= 0x80;
                }
     
                if ((source[source.Length - 1] & 0x01) != 0)
                {
                    dest[0] ^= 0x80;
     
                    if (dest.Length == 8)
                        dest[7] ^= 0x0D;
                    else
                        dest[15] ^= 0x43;
                }
            }
     
            public override void Initialize()
            {
                Array.Clear(_buffer, 0, _buffer.Length);
                _bufferPosition = 0;
            }
     
            protected override void HashCore(byte[] array, int ibStart, int cbSize)
            {
                if (_cipher == null)
                    CreateCipher();
     
                while (true)
                {
                    int count = Math.Min(cbSize, _buffer.Length - _bufferPosition);
     
                    for (int i = 0; i < count; i++)
                        _buffer[_bufferPosition++] ^= array[ibStart + i];
     
                    cbSize -= count;
                    if (cbSize == 0)
                        break;
     
                    _cipher.TransformBlock(_buffer, 0, _buffer.Length, _buffer, 0);
     
                    _bufferPosition = 0;
                    ibStart += count;
                }
            }
     
            protected override byte[] HashFinal()
            {
                if (_bufferPosition < _buffer.Length)
                {
                    _buffer[_bufferPosition] ^= 0x80;
     
                    for (int i = 0; i < _buffer.Length; i++)
                        _buffer[i] ^= _lu2[i];
                }
                else
                {
                    for (int i = 0; i < _buffer.Length; i++)
                        _buffer[i] ^= _lu1[i];
                }
     
                byte[] ret = new byte[_buffer.Length];
                _cipher.TransformBlock(_buffer, 0, _buffer.Length, ret, 0);
     
                return ret;
            }
     
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    if (_algorithm != null)
                    {
                        _algorithm.Clear();
                        _algorithm = null;
                    }
                    if (_cipher != null)
                    {
                        _cipher.Dispose();
                        _cipher = null;
                    }
                    if (_buffer != null)
                    {
                        Array.Clear(_buffer, 0, _buffer.Length);
                        _buffer = null;
                    }
                    if (_lu1 != null)
                    {
                        Array.Clear(_lu1, 0, _lu1.Length);
                        _lu1 = null;
                    }
                    if (_lu2 != null)
                    {
                        Array.Clear(_lu2, 0, _lu2.Length);
                        _lu2 = null;
                    }
                }
                base.Dispose(disposing);
            }
        }
    }
    Usage:
    Code (Text):
    OMAC omac = new OMAC();
    omac.Key = KEY;
    byte[] hash = omac.ComputeHash(data);
     
    Rip Cord and storm shadow like this.
  2. storm shadow

    Techbliss Owner Admin Ida Pro Expert Developer

    :cool:
    very nice
     
Top