115 lines
2.6 KiB
C#
115 lines
2.6 KiB
C#
|
using System;
|
|||
|
using Org.BouncyCastle.Crypto;
|
|||
|
using Org.BouncyCastle.Crypto.Digests;
|
|||
|
|
|||
|
namespace JXCMS.Core.Encrypt
|
|||
|
{
|
|||
|
public abstract class SM3Digest: IDigest
|
|||
|
{
|
|||
|
private const int BYTE_LENGTH = 64;
|
|||
|
|
|||
|
private byte[] xBuf;
|
|||
|
private int xBufOff;
|
|||
|
|
|||
|
private long byteCount;
|
|||
|
|
|||
|
internal SM3Digest()
|
|||
|
{
|
|||
|
xBuf = new byte[4];
|
|||
|
}
|
|||
|
|
|||
|
internal SM3Digest(SM3Digest t)
|
|||
|
{
|
|||
|
xBuf = new byte[t.xBuf.Length];
|
|||
|
Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
|
|||
|
|
|||
|
xBufOff = t.xBufOff;
|
|||
|
byteCount = t.byteCount;
|
|||
|
}
|
|||
|
|
|||
|
public void Update(byte input)
|
|||
|
{
|
|||
|
xBuf[xBufOff++] = input;
|
|||
|
|
|||
|
if (xBufOff == xBuf.Length)
|
|||
|
{
|
|||
|
ProcessWord(xBuf, 0);
|
|||
|
xBufOff = 0;
|
|||
|
}
|
|||
|
|
|||
|
byteCount++;
|
|||
|
}
|
|||
|
|
|||
|
public void BlockUpdate(
|
|||
|
byte[] input,
|
|||
|
int inOff,
|
|||
|
int length)
|
|||
|
{
|
|||
|
//
|
|||
|
// fill the current word
|
|||
|
//
|
|||
|
while ((xBufOff != 0) && (length > 0))
|
|||
|
{
|
|||
|
Update(input[inOff]);
|
|||
|
inOff++;
|
|||
|
length--;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// process whole words.
|
|||
|
//
|
|||
|
while (length > xBuf.Length)
|
|||
|
{
|
|||
|
ProcessWord(input, inOff);
|
|||
|
|
|||
|
inOff += xBuf.Length;
|
|||
|
length -= xBuf.Length;
|
|||
|
byteCount += xBuf.Length;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// load in the remainder.
|
|||
|
//
|
|||
|
while (length > 0)
|
|||
|
{
|
|||
|
Update(input[inOff]);
|
|||
|
|
|||
|
inOff++;
|
|||
|
length--;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Finish()
|
|||
|
{
|
|||
|
long bitLength = (byteCount << 3);
|
|||
|
|
|||
|
//
|
|||
|
// add the pad bytes.
|
|||
|
//
|
|||
|
Update((byte)128);
|
|||
|
|
|||
|
while (xBufOff != 0) Update((byte)0);
|
|||
|
ProcessLength(bitLength);
|
|||
|
ProcessBlock();
|
|||
|
}
|
|||
|
|
|||
|
public virtual void Reset()
|
|||
|
{
|
|||
|
byteCount = 0;
|
|||
|
xBufOff = 0;
|
|||
|
Array.Clear(xBuf, 0, xBuf.Length);
|
|||
|
}
|
|||
|
|
|||
|
public int GetByteLength()
|
|||
|
{
|
|||
|
return BYTE_LENGTH;
|
|||
|
}
|
|||
|
|
|||
|
internal abstract void ProcessWord(byte[] input, int inOff);
|
|||
|
internal abstract void ProcessLength(long bitLength);
|
|||
|
internal abstract void ProcessBlock();
|
|||
|
public abstract string AlgorithmName { get; }
|
|||
|
public abstract int GetDigestSize();
|
|||
|
public abstract int DoFinal(byte[] output, int outOff);
|
|||
|
}
|
|||
|
}
|