init commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Generators;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public class DHAgreement
|
||||
{
|
||||
private DHPrivateKeyParameters key;
|
||||
|
||||
private DHParameters dhParams;
|
||||
|
||||
private BigInteger privateValue;
|
||||
|
||||
private SecureRandom random;
|
||||
|
||||
public void Init(ICipherParameters parameters)
|
||||
{
|
||||
AsymmetricKeyParameter asymmetricKeyParameter;
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
|
||||
random = parametersWithRandom.Random;
|
||||
asymmetricKeyParameter = (AsymmetricKeyParameter)parametersWithRandom.Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
random = new SecureRandom();
|
||||
asymmetricKeyParameter = (AsymmetricKeyParameter)parameters;
|
||||
}
|
||||
if (!(asymmetricKeyParameter is DHPrivateKeyParameters))
|
||||
{
|
||||
throw new ArgumentException("DHEngine expects DHPrivateKeyParameters");
|
||||
}
|
||||
key = (DHPrivateKeyParameters)asymmetricKeyParameter;
|
||||
dhParams = key.Parameters;
|
||||
}
|
||||
|
||||
public BigInteger CalculateMessage()
|
||||
{
|
||||
DHKeyPairGenerator dHKeyPairGenerator = new DHKeyPairGenerator();
|
||||
dHKeyPairGenerator.Init(new DHKeyGenerationParameters(random, dhParams));
|
||||
AsymmetricCipherKeyPair asymmetricCipherKeyPair = dHKeyPairGenerator.GenerateKeyPair();
|
||||
privateValue = ((DHPrivateKeyParameters)asymmetricCipherKeyPair.Private).X;
|
||||
return ((DHPublicKeyParameters)asymmetricCipherKeyPair.Public).Y;
|
||||
}
|
||||
|
||||
public BigInteger CalculateAgreement(DHPublicKeyParameters pub, BigInteger message)
|
||||
{
|
||||
if (pub == null)
|
||||
{
|
||||
throw new ArgumentNullException("pub");
|
||||
}
|
||||
if (message == null)
|
||||
{
|
||||
throw new ArgumentNullException("message");
|
||||
}
|
||||
if (!pub.Parameters.Equals(dhParams))
|
||||
{
|
||||
throw new ArgumentException("Diffie-Hellman public key has wrong parameters.");
|
||||
}
|
||||
BigInteger p = dhParams.P;
|
||||
BigInteger y = pub.Y;
|
||||
if (y == null || y.CompareTo(BigInteger.One) <= 0 || y.CompareTo(p.Subtract(BigInteger.One)) >= 0)
|
||||
{
|
||||
throw new ArgumentException("Diffie-Hellman public key is weak");
|
||||
}
|
||||
BigInteger bigInteger = y.ModPow(privateValue, p);
|
||||
if (bigInteger.Equals(BigInteger.One))
|
||||
{
|
||||
throw new InvalidOperationException("Shared key can't be 1");
|
||||
}
|
||||
return message.ModPow(key.X, p).Multiply(bigInteger).Mod(p);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public class DHBasicAgreement : IBasicAgreement
|
||||
{
|
||||
private DHPrivateKeyParameters key;
|
||||
|
||||
private DHParameters dhParams;
|
||||
|
||||
public virtual void Init(ICipherParameters parameters)
|
||||
{
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
parameters = ((ParametersWithRandom)parameters).Parameters;
|
||||
}
|
||||
if (!(parameters is DHPrivateKeyParameters))
|
||||
{
|
||||
throw new ArgumentException("DHEngine expects DHPrivateKeyParameters");
|
||||
}
|
||||
key = (DHPrivateKeyParameters)parameters;
|
||||
dhParams = key.Parameters;
|
||||
}
|
||||
|
||||
public virtual int GetFieldSize()
|
||||
{
|
||||
return (key.Parameters.P.BitLength + 7) / 8;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateAgreement(ICipherParameters pubKey)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
throw new InvalidOperationException("Agreement algorithm not initialised");
|
||||
}
|
||||
DHPublicKeyParameters dHPublicKeyParameters = (DHPublicKeyParameters)pubKey;
|
||||
if (!dHPublicKeyParameters.Parameters.Equals(dhParams))
|
||||
{
|
||||
throw new ArgumentException("Diffie-Hellman public key has wrong parameters.");
|
||||
}
|
||||
BigInteger p = dhParams.P;
|
||||
BigInteger y = dHPublicKeyParameters.Y;
|
||||
if (y == null || y.CompareTo(BigInteger.One) <= 0 || y.CompareTo(p.Subtract(BigInteger.One)) >= 0)
|
||||
{
|
||||
throw new ArgumentException("Diffie-Hellman public key is weak");
|
||||
}
|
||||
BigInteger bigInteger = y.ModPow(key.X, p);
|
||||
if (bigInteger.Equals(BigInteger.One))
|
||||
{
|
||||
throw new InvalidOperationException("Shared key can't be 1");
|
||||
}
|
||||
return bigInteger;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public class DHStandardGroups
|
||||
{
|
||||
private static readonly string rfc2409_768_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF";
|
||||
|
||||
private static readonly string rfc2409_768_g = "02";
|
||||
|
||||
public static readonly DHParameters rfc2409_768 = FromPG(rfc2409_768_p, rfc2409_768_g);
|
||||
|
||||
private static readonly string rfc2409_1024_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF";
|
||||
|
||||
private static readonly string rfc2409_1024_g = "02";
|
||||
|
||||
public static readonly DHParameters rfc2409_1024 = FromPG(rfc2409_1024_p, rfc2409_1024_g);
|
||||
|
||||
private static readonly string rfc3526_1536_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF";
|
||||
|
||||
private static readonly string rfc3526_1536_g = "02";
|
||||
|
||||
public static readonly DHParameters rfc3526_1536 = FromPG(rfc3526_1536_p, rfc3526_1536_g);
|
||||
|
||||
private static readonly string rfc3526_2048_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF";
|
||||
|
||||
private static readonly string rfc3526_2048_g = "02";
|
||||
|
||||
public static readonly DHParameters rfc3526_2048 = FromPG(rfc3526_2048_p, rfc3526_2048_g);
|
||||
|
||||
private static readonly string rfc3526_3072_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
|
||||
|
||||
private static readonly string rfc3526_3072_g = "02";
|
||||
|
||||
public static readonly DHParameters rfc3526_3072 = FromPG(rfc3526_3072_p, rfc3526_3072_g);
|
||||
|
||||
private static readonly string rfc3526_4096_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF";
|
||||
|
||||
private static readonly string rfc3526_4096_g = "02";
|
||||
|
||||
public static readonly DHParameters rfc3526_4096 = FromPG(rfc3526_4096_p, rfc3526_4096_g);
|
||||
|
||||
private static readonly string rfc3526_6144_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF";
|
||||
|
||||
private static readonly string rfc3526_6144_g = "02";
|
||||
|
||||
public static readonly DHParameters rfc3526_6144 = FromPG(rfc3526_6144_p, rfc3526_6144_g);
|
||||
|
||||
private static readonly string rfc3526_8192_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF";
|
||||
|
||||
private static readonly string rfc3526_8192_g = "02";
|
||||
|
||||
public static readonly DHParameters rfc3526_8192 = FromPG(rfc3526_8192_p, rfc3526_8192_g);
|
||||
|
||||
public static readonly DHParameters rfc4306_768 = rfc2409_768;
|
||||
|
||||
public static readonly DHParameters rfc4306_1024 = rfc2409_1024;
|
||||
|
||||
private static readonly string rfc5114_1024_160_p = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371";
|
||||
|
||||
private static readonly string rfc5114_1024_160_g = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5";
|
||||
|
||||
private static readonly string rfc5114_1024_160_q = "F518AA8781A8DF278ABA4E7D64B7CB9D49462353";
|
||||
|
||||
[Obsolete("Existence of a 'hidden SNFS' backdoor cannot be ruled out.")]
|
||||
public static readonly DHParameters rfc5114_1024_160 = FromPGQ(rfc5114_1024_160_p, rfc5114_1024_160_g, rfc5114_1024_160_q);
|
||||
|
||||
private static readonly string rfc5114_2048_224_p = "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC2129037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708B3BF8A317091883681286130BC8985DB1602E714415D9330278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486DCDF93ACC44328387315D75E198C641A480CD86A1B9E587E8BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71CF9DE5384E71B81C0AC4DFFE0C10E64F";
|
||||
|
||||
private static readonly string rfc5114_2048_224_g = "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFAAB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7C17669101999024AF4D027275AC1348BB8A762D0521BC98AE247150422EA1ED409939D54DA7460CDB5F6C6B250717CBEF180EB34118E98D119529A45D6F834566E3025E316A330EFBB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC017981BC087F2A7065B384B890D3191F2BFA";
|
||||
|
||||
private static readonly string rfc5114_2048_224_q = "801C0D34C58D93FE997177101F80535A4738CEBCBF389A99B36371EB";
|
||||
|
||||
[Obsolete("Existence of a 'hidden SNFS' backdoor cannot be ruled out.")]
|
||||
public static readonly DHParameters rfc5114_2048_224 = FromPGQ(rfc5114_2048_224_p, rfc5114_2048_224_g, rfc5114_2048_224_q);
|
||||
|
||||
private static readonly string rfc5114_2048_256_p = "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597";
|
||||
|
||||
private static readonly string rfc5114_2048_256_g = "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659";
|
||||
|
||||
private static readonly string rfc5114_2048_256_q = "8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3";
|
||||
|
||||
[Obsolete("Existence of a 'hidden SNFS' backdoor cannot be ruled out.")]
|
||||
public static readonly DHParameters rfc5114_2048_256 = FromPGQ(rfc5114_2048_256_p, rfc5114_2048_256_g, rfc5114_2048_256_q);
|
||||
|
||||
public static readonly DHParameters rfc5996_768 = rfc4306_768;
|
||||
|
||||
public static readonly DHParameters rfc5996_1024 = rfc4306_1024;
|
||||
|
||||
private static readonly string rfc7919_ffdhe2048_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B423861285C97FFFFFFFFFFFFFFFF";
|
||||
|
||||
public static readonly DHParameters rfc7919_ffdhe2048 = Rfc7919Parameters(rfc7919_ffdhe2048_p, 225);
|
||||
|
||||
private static readonly string rfc7919_ffdhe3072_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF";
|
||||
|
||||
public static readonly DHParameters rfc7919_ffdhe3072 = Rfc7919Parameters(rfc7919_ffdhe3072_p, 275);
|
||||
|
||||
private static readonly string rfc7919_ffdhe4096_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6AFFFFFFFFFFFFFFFF";
|
||||
|
||||
public static readonly DHParameters rfc7919_ffdhe4096 = Rfc7919Parameters(rfc7919_ffdhe4096_p, 325);
|
||||
|
||||
private static readonly string rfc7919_ffdhe6144_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF";
|
||||
|
||||
public static readonly DHParameters rfc7919_ffdhe6144 = Rfc7919Parameters(rfc7919_ffdhe6144_p, 375);
|
||||
|
||||
private static readonly string rfc7919_ffdhe8192_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C8381E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665CB2C0F1CC01BD70229388839D2AF05E454504AC78B7582822846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA4571EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88CD68C8BB7C5C6424CFFFFFFFFFFFFFFFF";
|
||||
|
||||
public static readonly DHParameters rfc7919_ffdhe8192 = Rfc7919Parameters(rfc7919_ffdhe8192_p, 400);
|
||||
|
||||
private static BigInteger FromHex(string hex)
|
||||
{
|
||||
return new BigInteger(1, Hex.Decode(hex));
|
||||
}
|
||||
|
||||
private static DHParameters FromPG(string hexP, string hexG)
|
||||
{
|
||||
return new DHParameters(FromHex(hexP), FromHex(hexG));
|
||||
}
|
||||
|
||||
private static DHParameters FromPGQ(string hexP, string hexG, string hexQ)
|
||||
{
|
||||
return new DHParameters(FromHex(hexP), FromHex(hexG), FromHex(hexQ));
|
||||
}
|
||||
|
||||
private static DHParameters Rfc7919Parameters(string hexP, int l)
|
||||
{
|
||||
BigInteger bigInteger = FromHex(hexP);
|
||||
return new DHParameters(bigInteger, BigInteger.Two, bigInteger.ShiftRight(1), l);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Math.EC;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public class ECDHBasicAgreement : IBasicAgreement
|
||||
{
|
||||
protected internal ECPrivateKeyParameters privKey;
|
||||
|
||||
public virtual void Init(ICipherParameters parameters)
|
||||
{
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
parameters = ((ParametersWithRandom)parameters).Parameters;
|
||||
}
|
||||
privKey = (ECPrivateKeyParameters)parameters;
|
||||
}
|
||||
|
||||
public virtual int GetFieldSize()
|
||||
{
|
||||
return (privKey.Parameters.Curve.FieldSize + 7) / 8;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateAgreement(ICipherParameters pubKey)
|
||||
{
|
||||
ECPublicKeyParameters eCPublicKeyParameters = (ECPublicKeyParameters)pubKey;
|
||||
ECDomainParameters parameters = privKey.Parameters;
|
||||
if (!parameters.Equals(eCPublicKeyParameters.Parameters))
|
||||
{
|
||||
throw new InvalidOperationException("ECDH public key has wrong domain parameters");
|
||||
}
|
||||
BigInteger bigInteger = privKey.D;
|
||||
ECPoint eCPoint = ECAlgorithms.CleanPoint(parameters.Curve, eCPublicKeyParameters.Q);
|
||||
if (eCPoint.IsInfinity)
|
||||
{
|
||||
throw new InvalidOperationException("Infinity is not a valid public key for ECDH");
|
||||
}
|
||||
BigInteger h = parameters.H;
|
||||
if (!h.Equals(BigInteger.One))
|
||||
{
|
||||
bigInteger = parameters.HInv.Multiply(bigInteger).Mod(parameters.N);
|
||||
eCPoint = ECAlgorithms.ReferenceMultiply(eCPoint, h);
|
||||
}
|
||||
ECPoint eCPoint2 = eCPoint.Multiply(bigInteger).Normalize();
|
||||
if (eCPoint2.IsInfinity)
|
||||
{
|
||||
throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH");
|
||||
}
|
||||
return eCPoint2.AffineXCoord.ToBigInteger();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Math.EC;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public class ECDHCBasicAgreement : IBasicAgreement
|
||||
{
|
||||
private ECPrivateKeyParameters privKey;
|
||||
|
||||
public virtual void Init(ICipherParameters parameters)
|
||||
{
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
parameters = ((ParametersWithRandom)parameters).Parameters;
|
||||
}
|
||||
privKey = (ECPrivateKeyParameters)parameters;
|
||||
}
|
||||
|
||||
public virtual int GetFieldSize()
|
||||
{
|
||||
return (privKey.Parameters.Curve.FieldSize + 7) / 8;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateAgreement(ICipherParameters pubKey)
|
||||
{
|
||||
ECPublicKeyParameters eCPublicKeyParameters = (ECPublicKeyParameters)pubKey;
|
||||
ECDomainParameters parameters = privKey.Parameters;
|
||||
if (!parameters.Equals(eCPublicKeyParameters.Parameters))
|
||||
{
|
||||
throw new InvalidOperationException("ECDHC public key has wrong domain parameters");
|
||||
}
|
||||
BigInteger b = parameters.H.Multiply(privKey.D).Mod(parameters.N);
|
||||
ECPoint eCPoint = ECAlgorithms.CleanPoint(parameters.Curve, eCPublicKeyParameters.Q);
|
||||
if (eCPoint.IsInfinity)
|
||||
{
|
||||
throw new InvalidOperationException("Infinity is not a valid public key for ECDHC");
|
||||
}
|
||||
ECPoint eCPoint2 = eCPoint.Multiply(b).Normalize();
|
||||
if (eCPoint2.IsInfinity)
|
||||
{
|
||||
throw new InvalidOperationException("Infinity is not a valid agreement value for ECDHC");
|
||||
}
|
||||
return eCPoint2.AffineXCoord.ToBigInteger();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using Org.BouncyCastle.Crypto.Agreement.Kdf;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public class ECDHWithKdfBasicAgreement : ECDHBasicAgreement
|
||||
{
|
||||
private readonly string algorithm;
|
||||
|
||||
private readonly IDerivationFunction kdf;
|
||||
|
||||
public ECDHWithKdfBasicAgreement(string algorithm, IDerivationFunction kdf)
|
||||
{
|
||||
if (algorithm == null)
|
||||
{
|
||||
throw new ArgumentNullException("algorithm");
|
||||
}
|
||||
if (kdf == null)
|
||||
{
|
||||
throw new ArgumentNullException("kdf");
|
||||
}
|
||||
this.algorithm = algorithm;
|
||||
this.kdf = kdf;
|
||||
}
|
||||
|
||||
public override BigInteger CalculateAgreement(ICipherParameters pubKey)
|
||||
{
|
||||
BigInteger r = base.CalculateAgreement(pubKey);
|
||||
int defaultKeySize = GeneratorUtilities.GetDefaultKeySize(algorithm);
|
||||
DHKdfParameters parameters = new DHKdfParameters(new DerObjectIdentifier(algorithm), defaultKeySize, BigIntToBytes(r));
|
||||
kdf.Init(parameters);
|
||||
byte[] array = new byte[defaultKeySize / 8];
|
||||
kdf.GenerateBytes(array, 0, array.Length);
|
||||
return new BigInteger(1, array);
|
||||
}
|
||||
|
||||
private byte[] BigIntToBytes(BigInteger r)
|
||||
{
|
||||
int byteLength = X9IntegerConverter.GetByteLength(privKey.Parameters.Curve);
|
||||
return X9IntegerConverter.IntegerToBytes(r, byteLength);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Math.EC;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public class ECMqvBasicAgreement : IBasicAgreement
|
||||
{
|
||||
protected internal MqvPrivateParameters privParams;
|
||||
|
||||
public virtual void Init(ICipherParameters parameters)
|
||||
{
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
parameters = ((ParametersWithRandom)parameters).Parameters;
|
||||
}
|
||||
privParams = (MqvPrivateParameters)parameters;
|
||||
}
|
||||
|
||||
public virtual int GetFieldSize()
|
||||
{
|
||||
return (privParams.StaticPrivateKey.Parameters.Curve.FieldSize + 7) / 8;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateAgreement(ICipherParameters pubKey)
|
||||
{
|
||||
MqvPublicParameters mqvPublicParameters = (MqvPublicParameters)pubKey;
|
||||
ECPrivateKeyParameters staticPrivateKey = privParams.StaticPrivateKey;
|
||||
ECDomainParameters parameters = staticPrivateKey.Parameters;
|
||||
if (!parameters.Equals(mqvPublicParameters.StaticPublicKey.Parameters))
|
||||
{
|
||||
throw new InvalidOperationException("ECMQV public key components have wrong domain parameters");
|
||||
}
|
||||
ECPoint eCPoint = CalculateMqvAgreement(parameters, staticPrivateKey, privParams.EphemeralPrivateKey, privParams.EphemeralPublicKey, mqvPublicParameters.StaticPublicKey, mqvPublicParameters.EphemeralPublicKey).Normalize();
|
||||
if (eCPoint.IsInfinity)
|
||||
{
|
||||
throw new InvalidOperationException("Infinity is not a valid agreement value for MQV");
|
||||
}
|
||||
return eCPoint.AffineXCoord.ToBigInteger();
|
||||
}
|
||||
|
||||
private static ECPoint CalculateMqvAgreement(ECDomainParameters parameters, ECPrivateKeyParameters d1U, ECPrivateKeyParameters d2U, ECPublicKeyParameters Q2U, ECPublicKeyParameters Q1V, ECPublicKeyParameters Q2V)
|
||||
{
|
||||
BigInteger n = parameters.N;
|
||||
int num = (n.BitLength + 1) / 2;
|
||||
BigInteger m = BigInteger.One.ShiftLeft(num);
|
||||
ECCurve curve = parameters.Curve;
|
||||
ECPoint eCPoint = ECAlgorithms.CleanPoint(curve, Q2U.Q);
|
||||
ECPoint p = ECAlgorithms.CleanPoint(curve, Q1V.Q);
|
||||
ECPoint eCPoint2 = ECAlgorithms.CleanPoint(curve, Q2V.Q);
|
||||
BigInteger bigInteger = eCPoint.AffineXCoord.ToBigInteger();
|
||||
BigInteger bigInteger2 = bigInteger.Mod(m);
|
||||
BigInteger val = bigInteger2.SetBit(num);
|
||||
BigInteger val2 = d1U.D.Multiply(val).Add(d2U.D).Mod(n);
|
||||
BigInteger bigInteger3 = eCPoint2.AffineXCoord.ToBigInteger();
|
||||
BigInteger bigInteger4 = bigInteger3.Mod(m);
|
||||
BigInteger bigInteger5 = bigInteger4.SetBit(num);
|
||||
BigInteger bigInteger6 = parameters.H.Multiply(val2).Mod(n);
|
||||
return ECAlgorithms.SumOfTwoMultiplies(p, bigInteger5.Multiply(bigInteger6).Mod(n), eCPoint2, bigInteger6);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using Org.BouncyCastle.Crypto.Agreement.Kdf;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public class ECMqvWithKdfBasicAgreement : ECMqvBasicAgreement
|
||||
{
|
||||
private readonly string algorithm;
|
||||
|
||||
private readonly IDerivationFunction kdf;
|
||||
|
||||
public ECMqvWithKdfBasicAgreement(string algorithm, IDerivationFunction kdf)
|
||||
{
|
||||
if (algorithm == null)
|
||||
{
|
||||
throw new ArgumentNullException("algorithm");
|
||||
}
|
||||
if (kdf == null)
|
||||
{
|
||||
throw new ArgumentNullException("kdf");
|
||||
}
|
||||
this.algorithm = algorithm;
|
||||
this.kdf = kdf;
|
||||
}
|
||||
|
||||
public override BigInteger CalculateAgreement(ICipherParameters pubKey)
|
||||
{
|
||||
BigInteger r = base.CalculateAgreement(pubKey);
|
||||
int defaultKeySize = GeneratorUtilities.GetDefaultKeySize(algorithm);
|
||||
DHKdfParameters parameters = new DHKdfParameters(new DerObjectIdentifier(algorithm), defaultKeySize, BigIntToBytes(r));
|
||||
kdf.Init(parameters);
|
||||
byte[] array = new byte[defaultKeySize / 8];
|
||||
kdf.GenerateBytes(array, 0, array.Length);
|
||||
return new BigInteger(1, array);
|
||||
}
|
||||
|
||||
private byte[] BigIntToBytes(BigInteger r)
|
||||
{
|
||||
int byteLength = X9IntegerConverter.GetByteLength(privParams.StaticPrivateKey.Parameters.Curve);
|
||||
return X9IntegerConverter.IntegerToBytes(r, byteLength);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Digests;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.JPake;
|
||||
|
||||
public class JPakeParticipant
|
||||
{
|
||||
public static readonly int STATE_INITIALIZED = 0;
|
||||
|
||||
public static readonly int STATE_ROUND_1_CREATED = 10;
|
||||
|
||||
public static readonly int STATE_ROUND_1_VALIDATED = 20;
|
||||
|
||||
public static readonly int STATE_ROUND_2_CREATED = 30;
|
||||
|
||||
public static readonly int STATE_ROUND_2_VALIDATED = 40;
|
||||
|
||||
public static readonly int STATE_KEY_CALCULATED = 50;
|
||||
|
||||
public static readonly int STATE_ROUND_3_CREATED = 60;
|
||||
|
||||
public static readonly int STATE_ROUND_3_VALIDATED = 70;
|
||||
|
||||
private string participantId;
|
||||
|
||||
private char[] password;
|
||||
|
||||
private IDigest digest;
|
||||
|
||||
private readonly SecureRandom random;
|
||||
|
||||
private readonly BigInteger p;
|
||||
|
||||
private readonly BigInteger q;
|
||||
|
||||
private readonly BigInteger g;
|
||||
|
||||
private string partnerParticipantId;
|
||||
|
||||
private BigInteger x1;
|
||||
|
||||
private BigInteger x2;
|
||||
|
||||
private BigInteger gx1;
|
||||
|
||||
private BigInteger gx2;
|
||||
|
||||
private BigInteger gx3;
|
||||
|
||||
private BigInteger gx4;
|
||||
|
||||
private BigInteger b;
|
||||
|
||||
private int state;
|
||||
|
||||
public virtual int State => state;
|
||||
|
||||
public JPakeParticipant(string participantId, char[] password)
|
||||
: this(participantId, password, JPakePrimeOrderGroups.NIST_3072)
|
||||
{
|
||||
}
|
||||
|
||||
public JPakeParticipant(string participantId, char[] password, JPakePrimeOrderGroup group)
|
||||
: this(participantId, password, group, new Sha256Digest(), new SecureRandom())
|
||||
{
|
||||
}
|
||||
|
||||
public JPakeParticipant(string participantId, char[] password, JPakePrimeOrderGroup group, IDigest digest, SecureRandom random)
|
||||
{
|
||||
JPakeUtilities.ValidateNotNull(participantId, "participantId");
|
||||
JPakeUtilities.ValidateNotNull(password, "password");
|
||||
JPakeUtilities.ValidateNotNull(group, "p");
|
||||
JPakeUtilities.ValidateNotNull(digest, "digest");
|
||||
JPakeUtilities.ValidateNotNull(random, "random");
|
||||
if (password.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("Password must not be empty.");
|
||||
}
|
||||
this.participantId = participantId;
|
||||
this.password = new char[password.Length];
|
||||
Array.Copy(password, this.password, password.Length);
|
||||
p = group.P;
|
||||
q = group.Q;
|
||||
g = group.G;
|
||||
this.digest = digest;
|
||||
this.random = random;
|
||||
state = STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
public virtual JPakeRound1Payload CreateRound1PayloadToSend()
|
||||
{
|
||||
if (state >= STATE_ROUND_1_CREATED)
|
||||
{
|
||||
throw new InvalidOperationException("Round 1 payload already created for " + participantId);
|
||||
}
|
||||
x1 = JPakeUtilities.GenerateX1(q, random);
|
||||
x2 = JPakeUtilities.GenerateX2(q, random);
|
||||
gx1 = JPakeUtilities.CalculateGx(p, g, x1);
|
||||
gx2 = JPakeUtilities.CalculateGx(p, g, x2);
|
||||
BigInteger[] knowledgeProofForX = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, g, gx1, x1, participantId, digest, random);
|
||||
BigInteger[] knowledgeProofForX2 = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, g, gx2, x2, participantId, digest, random);
|
||||
state = STATE_ROUND_1_CREATED;
|
||||
return new JPakeRound1Payload(participantId, gx1, gx2, knowledgeProofForX, knowledgeProofForX2);
|
||||
}
|
||||
|
||||
public virtual void ValidateRound1PayloadReceived(JPakeRound1Payload round1PayloadReceived)
|
||||
{
|
||||
if (state >= STATE_ROUND_1_VALIDATED)
|
||||
{
|
||||
throw new InvalidOperationException("Validation already attempted for round 1 payload for " + participantId);
|
||||
}
|
||||
partnerParticipantId = round1PayloadReceived.ParticipantId;
|
||||
gx3 = round1PayloadReceived.Gx1;
|
||||
gx4 = round1PayloadReceived.Gx2;
|
||||
BigInteger[] knowledgeProofForX = round1PayloadReceived.KnowledgeProofForX1;
|
||||
BigInteger[] knowledgeProofForX2 = round1PayloadReceived.KnowledgeProofForX2;
|
||||
JPakeUtilities.ValidateParticipantIdsDiffer(participantId, round1PayloadReceived.ParticipantId);
|
||||
JPakeUtilities.ValidateGx4(gx4);
|
||||
JPakeUtilities.ValidateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX, round1PayloadReceived.ParticipantId, digest);
|
||||
JPakeUtilities.ValidateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX2, round1PayloadReceived.ParticipantId, digest);
|
||||
state = STATE_ROUND_1_VALIDATED;
|
||||
}
|
||||
|
||||
public virtual JPakeRound2Payload CreateRound2PayloadToSend()
|
||||
{
|
||||
if (state >= STATE_ROUND_2_CREATED)
|
||||
{
|
||||
throw new InvalidOperationException("Round 2 payload already created for " + participantId);
|
||||
}
|
||||
if (state < STATE_ROUND_1_VALIDATED)
|
||||
{
|
||||
throw new InvalidOperationException("Round 1 payload must be validated prior to creating round 2 payload for " + participantId);
|
||||
}
|
||||
BigInteger gA = JPakeUtilities.CalculateGA(p, gx1, gx3, gx4);
|
||||
BigInteger s = JPakeUtilities.CalculateS(password);
|
||||
BigInteger bigInteger = JPakeUtilities.CalculateX2s(q, x2, s);
|
||||
BigInteger bigInteger2 = JPakeUtilities.CalculateA(p, q, gA, bigInteger);
|
||||
BigInteger[] knowledgeProofForX2s = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, gA, bigInteger2, bigInteger, participantId, digest, random);
|
||||
state = STATE_ROUND_2_CREATED;
|
||||
return new JPakeRound2Payload(participantId, bigInteger2, knowledgeProofForX2s);
|
||||
}
|
||||
|
||||
public virtual void ValidateRound2PayloadReceived(JPakeRound2Payload round2PayloadReceived)
|
||||
{
|
||||
if (state >= STATE_ROUND_2_VALIDATED)
|
||||
{
|
||||
throw new InvalidOperationException("Validation already attempted for round 2 payload for " + participantId);
|
||||
}
|
||||
if (state < STATE_ROUND_1_VALIDATED)
|
||||
{
|
||||
throw new InvalidOperationException("Round 1 payload must be validated prior to validation round 2 payload for " + participantId);
|
||||
}
|
||||
BigInteger ga = JPakeUtilities.CalculateGA(p, gx3, gx1, gx2);
|
||||
b = round2PayloadReceived.A;
|
||||
BigInteger[] knowledgeProofForX2s = round2PayloadReceived.KnowledgeProofForX2s;
|
||||
JPakeUtilities.ValidateParticipantIdsDiffer(participantId, round2PayloadReceived.ParticipantId);
|
||||
JPakeUtilities.ValidateParticipantIdsEqual(partnerParticipantId, round2PayloadReceived.ParticipantId);
|
||||
JPakeUtilities.ValidateGa(ga);
|
||||
JPakeUtilities.ValidateZeroKnowledgeProof(p, q, ga, b, knowledgeProofForX2s, round2PayloadReceived.ParticipantId, digest);
|
||||
state = STATE_ROUND_2_VALIDATED;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateKeyingMaterial()
|
||||
{
|
||||
if (state >= STATE_KEY_CALCULATED)
|
||||
{
|
||||
throw new InvalidOperationException("Key already calculated for " + participantId);
|
||||
}
|
||||
if (state < STATE_ROUND_2_VALIDATED)
|
||||
{
|
||||
throw new InvalidOperationException("Round 2 payload must be validated prior to creating key for " + participantId);
|
||||
}
|
||||
BigInteger s = JPakeUtilities.CalculateS(password);
|
||||
Array.Clear(password, 0, password.Length);
|
||||
password = null;
|
||||
BigInteger result = JPakeUtilities.CalculateKeyingMaterial(p, q, gx4, x2, s, b);
|
||||
x1 = null;
|
||||
x2 = null;
|
||||
b = null;
|
||||
state = STATE_KEY_CALCULATED;
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual JPakeRound3Payload CreateRound3PayloadToSend(BigInteger keyingMaterial)
|
||||
{
|
||||
if (state >= STATE_ROUND_3_CREATED)
|
||||
{
|
||||
throw new InvalidOperationException("Round 3 payload already created for " + participantId);
|
||||
}
|
||||
if (state < STATE_KEY_CALCULATED)
|
||||
{
|
||||
throw new InvalidOperationException("Keying material must be calculated prior to creating round 3 payload for " + participantId);
|
||||
}
|
||||
BigInteger magTag = JPakeUtilities.CalculateMacTag(participantId, partnerParticipantId, gx1, gx2, gx3, gx4, keyingMaterial, digest);
|
||||
state = STATE_ROUND_3_CREATED;
|
||||
return new JPakeRound3Payload(participantId, magTag);
|
||||
}
|
||||
|
||||
public virtual void ValidateRound3PayloadReceived(JPakeRound3Payload round3PayloadReceived, BigInteger keyingMaterial)
|
||||
{
|
||||
if (state >= STATE_ROUND_3_VALIDATED)
|
||||
{
|
||||
throw new InvalidOperationException("Validation already attempted for round 3 payload for " + participantId);
|
||||
}
|
||||
if (state < STATE_KEY_CALCULATED)
|
||||
{
|
||||
throw new InvalidOperationException("Keying material must be calculated prior to validating round 3 payload for " + participantId);
|
||||
}
|
||||
JPakeUtilities.ValidateParticipantIdsDiffer(participantId, round3PayloadReceived.ParticipantId);
|
||||
JPakeUtilities.ValidateParticipantIdsEqual(partnerParticipantId, round3PayloadReceived.ParticipantId);
|
||||
JPakeUtilities.ValidateMacTag(participantId, partnerParticipantId, gx1, gx2, gx3, gx4, keyingMaterial, digest, round3PayloadReceived.MacTag);
|
||||
gx1 = null;
|
||||
gx2 = null;
|
||||
gx3 = null;
|
||||
gx4 = null;
|
||||
state = STATE_ROUND_3_VALIDATED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.JPake;
|
||||
|
||||
public class JPakePrimeOrderGroup
|
||||
{
|
||||
private readonly BigInteger p;
|
||||
|
||||
private readonly BigInteger q;
|
||||
|
||||
private readonly BigInteger g;
|
||||
|
||||
public virtual BigInteger P => p;
|
||||
|
||||
public virtual BigInteger Q => q;
|
||||
|
||||
public virtual BigInteger G => g;
|
||||
|
||||
public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g)
|
||||
: this(p, q, g, skipChecks: false)
|
||||
{
|
||||
}
|
||||
|
||||
public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, bool skipChecks)
|
||||
{
|
||||
JPakeUtilities.ValidateNotNull(p, "p");
|
||||
JPakeUtilities.ValidateNotNull(q, "q");
|
||||
JPakeUtilities.ValidateNotNull(g, "g");
|
||||
if (!skipChecks)
|
||||
{
|
||||
if (!p.Subtract(JPakeUtilities.One).Mod(q).Equals(JPakeUtilities.Zero))
|
||||
{
|
||||
throw new ArgumentException("p-1 must be evenly divisible by q");
|
||||
}
|
||||
if (g.CompareTo(BigInteger.Two) == -1 || g.CompareTo(p.Subtract(JPakeUtilities.One)) == 1)
|
||||
{
|
||||
throw new ArgumentException("g must be in [2, p-1]");
|
||||
}
|
||||
if (!g.ModPow(q, p).Equals(JPakeUtilities.One))
|
||||
{
|
||||
throw new ArgumentException("g^q mod p must equal 1");
|
||||
}
|
||||
if (!p.IsProbablePrime(20))
|
||||
{
|
||||
throw new ArgumentException("p must be prime");
|
||||
}
|
||||
if (!q.IsProbablePrime(20))
|
||||
{
|
||||
throw new ArgumentException("q must be prime");
|
||||
}
|
||||
}
|
||||
this.p = p;
|
||||
this.q = q;
|
||||
this.g = g;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.JPake;
|
||||
|
||||
public class JPakePrimeOrderGroups
|
||||
{
|
||||
public static readonly JPakePrimeOrderGroup SUN_JCE_1024 = new JPakePrimeOrderGroup(new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16), new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16), new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16), skipChecks: true);
|
||||
|
||||
public static readonly JPakePrimeOrderGroup NIST_2048 = new JPakePrimeOrderGroup(new BigInteger("C196BA05AC29E1F9C3C72D56DFFC6154A033F1477AC88EC37F09BE6C5BB95F51C296DD20D1A28A067CCC4D4316A4BD1DCA55ED1066D438C35AEBAABF57E7DAE428782A95ECA1C143DB701FD48533A3C18F0FE23557EA7AE619ECACC7E0B51652A8776D02A425567DED36EABD90CA33A1E8D988F0BBB92D02D1D20290113BB562CE1FC856EEB7CDD92D33EEA6F410859B179E7E789A8F75F645FAE2E136D252BFFAFF89528945C1ABE705A38DBC2D364AADE99BE0D0AAD82E5320121496DC65B3930E38047294FF877831A16D5228418DE8AB275D7D75651CEFED65F78AFC3EA7FE4D79B35F62A0402A1117599ADAC7B269A59F353CF450E6982D3B1702D9CA83", 16), new BigInteger("90EAF4D1AF0708B1B612FF35E0A2997EB9E9D263C9CE659528945C0D", 16), new BigInteger("A59A749A11242C58C894E9E5A91804E8FA0AC64B56288F8D47D51B1EDC4D65444FECA0111D78F35FC9FDD4CB1F1B79A3BA9CBEE83A3F811012503C8117F98E5048B089E387AF6949BF8784EBD9EF45876F2E6A5A495BE64B6E770409494B7FEE1DBB1E4B2BC2A53D4F893D418B7159592E4FFFDF6969E91D770DAEBD0B5CB14C00AD68EC7DC1E5745EA55C706C4A1C5C88964E34D09DEB753AD418C1AD0F4FDFD049A955E5D78491C0B7A2F1575A008CCD727AB376DB6E695515B05BD412F5B8C2F4C77EE10DA48ABD53F5DD498927EE7B692BBBCDA2FB23A516C5B4533D73980B2A3B60E384ED200AE21B40D273651AD6060C13D97FD69AA13C5611A51B9085", 16), skipChecks: true);
|
||||
|
||||
public static readonly JPakePrimeOrderGroup NIST_3072 = new JPakePrimeOrderGroup(new BigInteger("90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA129F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D15939487E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773EBE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941DAD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504FB0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328EC22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73", 16), new BigInteger("CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D", 16), new BigInteger("5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE3B7ACCC54D521E37F84A4BDD5B06B0970CC2D2BBB715F7B82846F9A0C393914C792E6A923E2117AB805276A975AADB5261D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A60126FEB2CF05DB8A7F0F09B3397F3937F2E90B9E5B9C9B6EFEF642BC48351C46FB171B9BFA9EF17A961CE96C7E7A7CC3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B67299E231F8BD90B39AC3AE3BE0C6B6CACEF8289A2E2873D58E51E029CAFBD55E6841489AB66B5B4B9BA6E2F784660896AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B988567A88126B914D7828E2B63A6D7ED0747EC59E0E0A23CE7D8A74C1D2C2A7AFB6A29799620F00E11C33787F7DED3B30E1A22D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B", 16), skipChecks: true);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.JPake;
|
||||
|
||||
public class JPakeRound1Payload
|
||||
{
|
||||
private readonly string participantId;
|
||||
|
||||
private readonly BigInteger gx1;
|
||||
|
||||
private readonly BigInteger gx2;
|
||||
|
||||
private readonly BigInteger[] knowledgeProofForX1;
|
||||
|
||||
private readonly BigInteger[] knowledgeProofForX2;
|
||||
|
||||
public virtual string ParticipantId => participantId;
|
||||
|
||||
public virtual BigInteger Gx1 => gx1;
|
||||
|
||||
public virtual BigInteger Gx2 => gx2;
|
||||
|
||||
public virtual BigInteger[] KnowledgeProofForX1
|
||||
{
|
||||
get
|
||||
{
|
||||
BigInteger[] array = new BigInteger[knowledgeProofForX1.Length];
|
||||
Array.Copy(knowledgeProofForX1, array, knowledgeProofForX1.Length);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger[] KnowledgeProofForX2
|
||||
{
|
||||
get
|
||||
{
|
||||
BigInteger[] array = new BigInteger[knowledgeProofForX2.Length];
|
||||
Array.Copy(knowledgeProofForX2, array, knowledgeProofForX2.Length);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
public JPakeRound1Payload(string participantId, BigInteger gx1, BigInteger gx2, BigInteger[] knowledgeProofForX1, BigInteger[] knowledgeProofForX2)
|
||||
{
|
||||
JPakeUtilities.ValidateNotNull(participantId, "participantId");
|
||||
JPakeUtilities.ValidateNotNull(gx1, "gx1");
|
||||
JPakeUtilities.ValidateNotNull(gx2, "gx2");
|
||||
JPakeUtilities.ValidateNotNull(knowledgeProofForX1, "knowledgeProofForX1");
|
||||
JPakeUtilities.ValidateNotNull(knowledgeProofForX2, "knowledgeProofForX2");
|
||||
this.participantId = participantId;
|
||||
this.gx1 = gx1;
|
||||
this.gx2 = gx2;
|
||||
this.knowledgeProofForX1 = new BigInteger[knowledgeProofForX1.Length];
|
||||
Array.Copy(knowledgeProofForX1, this.knowledgeProofForX1, knowledgeProofForX1.Length);
|
||||
this.knowledgeProofForX2 = new BigInteger[knowledgeProofForX2.Length];
|
||||
Array.Copy(knowledgeProofForX2, this.knowledgeProofForX2, knowledgeProofForX2.Length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.JPake;
|
||||
|
||||
public class JPakeRound2Payload
|
||||
{
|
||||
private readonly string participantId;
|
||||
|
||||
private readonly BigInteger a;
|
||||
|
||||
private readonly BigInteger[] knowledgeProofForX2s;
|
||||
|
||||
public virtual string ParticipantId => participantId;
|
||||
|
||||
public virtual BigInteger A => a;
|
||||
|
||||
public virtual BigInteger[] KnowledgeProofForX2s
|
||||
{
|
||||
get
|
||||
{
|
||||
BigInteger[] array = new BigInteger[knowledgeProofForX2s.Length];
|
||||
Array.Copy(knowledgeProofForX2s, array, knowledgeProofForX2s.Length);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
public JPakeRound2Payload(string participantId, BigInteger a, BigInteger[] knowledgeProofForX2s)
|
||||
{
|
||||
JPakeUtilities.ValidateNotNull(participantId, "participantId");
|
||||
JPakeUtilities.ValidateNotNull(a, "a");
|
||||
JPakeUtilities.ValidateNotNull(knowledgeProofForX2s, "knowledgeProofForX2s");
|
||||
this.participantId = participantId;
|
||||
this.a = a;
|
||||
this.knowledgeProofForX2s = new BigInteger[knowledgeProofForX2s.Length];
|
||||
knowledgeProofForX2s.CopyTo(this.knowledgeProofForX2s, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.JPake;
|
||||
|
||||
public class JPakeRound3Payload
|
||||
{
|
||||
private readonly string participantId;
|
||||
|
||||
private readonly BigInteger macTag;
|
||||
|
||||
public virtual string ParticipantId => participantId;
|
||||
|
||||
public virtual BigInteger MacTag => macTag;
|
||||
|
||||
public JPakeRound3Payload(string participantId, BigInteger magTag)
|
||||
{
|
||||
this.participantId = participantId;
|
||||
macTag = magTag;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Crypto.Macs;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.JPake;
|
||||
|
||||
public abstract class JPakeUtilities
|
||||
{
|
||||
public static readonly BigInteger Zero = BigInteger.Zero;
|
||||
|
||||
public static readonly BigInteger One = BigInteger.One;
|
||||
|
||||
public static BigInteger GenerateX1(BigInteger q, SecureRandom random)
|
||||
{
|
||||
BigInteger zero = Zero;
|
||||
BigInteger max = q.Subtract(One);
|
||||
return BigIntegers.CreateRandomInRange(zero, max, random);
|
||||
}
|
||||
|
||||
public static BigInteger GenerateX2(BigInteger q, SecureRandom random)
|
||||
{
|
||||
BigInteger one = One;
|
||||
BigInteger max = q.Subtract(One);
|
||||
return BigIntegers.CreateRandomInRange(one, max, random);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateS(char[] password)
|
||||
{
|
||||
return new BigInteger(Encoding.UTF8.GetBytes(password));
|
||||
}
|
||||
|
||||
public static BigInteger CalculateGx(BigInteger p, BigInteger g, BigInteger x)
|
||||
{
|
||||
return g.ModPow(x, p);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateGA(BigInteger p, BigInteger gx1, BigInteger gx3, BigInteger gx4)
|
||||
{
|
||||
return gx1.Multiply(gx3).Multiply(gx4).Mod(p);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateX2s(BigInteger q, BigInteger x2, BigInteger s)
|
||||
{
|
||||
return x2.Multiply(s).Mod(q);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateA(BigInteger p, BigInteger q, BigInteger gA, BigInteger x2s)
|
||||
{
|
||||
return gA.ModPow(x2s, p);
|
||||
}
|
||||
|
||||
public static BigInteger[] CalculateZeroKnowledgeProof(BigInteger p, BigInteger q, BigInteger g, BigInteger gx, BigInteger x, string participantId, IDigest digest, SecureRandom random)
|
||||
{
|
||||
BigInteger zero = Zero;
|
||||
BigInteger max = q.Subtract(One);
|
||||
BigInteger bigInteger = BigIntegers.CreateRandomInRange(zero, max, random);
|
||||
BigInteger bigInteger2 = g.ModPow(bigInteger, p);
|
||||
BigInteger val = CalculateHashForZeroKnowledgeProof(g, bigInteger2, gx, participantId, digest);
|
||||
return new BigInteger[2]
|
||||
{
|
||||
bigInteger2,
|
||||
bigInteger.Subtract(x.Multiply(val)).Mod(q)
|
||||
};
|
||||
}
|
||||
|
||||
private static BigInteger CalculateHashForZeroKnowledgeProof(BigInteger g, BigInteger gr, BigInteger gx, string participantId, IDigest digest)
|
||||
{
|
||||
digest.Reset();
|
||||
UpdateDigestIncludingSize(digest, g);
|
||||
UpdateDigestIncludingSize(digest, gr);
|
||||
UpdateDigestIncludingSize(digest, gx);
|
||||
UpdateDigestIncludingSize(digest, participantId);
|
||||
byte[] bytes = DigestUtilities.DoFinal(digest);
|
||||
return new BigInteger(bytes);
|
||||
}
|
||||
|
||||
public static void ValidateGx4(BigInteger gx4)
|
||||
{
|
||||
if (gx4.Equals(One))
|
||||
{
|
||||
throw new CryptoException("g^x validation failed. g^x should not be 1.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ValidateGa(BigInteger ga)
|
||||
{
|
||||
if (ga.Equals(One))
|
||||
{
|
||||
throw new CryptoException("ga is equal to 1. It should not be. The chances of this happening are on the order of 2^160 for a 160-bit q. Try again.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ValidateZeroKnowledgeProof(BigInteger p, BigInteger q, BigInteger g, BigInteger gx, BigInteger[] zeroKnowledgeProof, string participantId, IDigest digest)
|
||||
{
|
||||
BigInteger bigInteger = zeroKnowledgeProof[0];
|
||||
BigInteger e = zeroKnowledgeProof[1];
|
||||
BigInteger e2 = CalculateHashForZeroKnowledgeProof(g, bigInteger, gx, participantId, digest);
|
||||
if (gx.CompareTo(Zero) != 1 || gx.CompareTo(p) != -1 || gx.ModPow(q, p).CompareTo(One) != 0 || g.ModPow(e, p).Multiply(gx.ModPow(e2, p)).Mod(p)
|
||||
.CompareTo(bigInteger) != 0)
|
||||
{
|
||||
throw new CryptoException("Zero-knowledge proof validation failed");
|
||||
}
|
||||
}
|
||||
|
||||
public static BigInteger CalculateKeyingMaterial(BigInteger p, BigInteger q, BigInteger gx4, BigInteger x2, BigInteger s, BigInteger B)
|
||||
{
|
||||
return gx4.ModPow(x2.Multiply(s).Negate().Mod(q), p).Multiply(B).ModPow(x2, p);
|
||||
}
|
||||
|
||||
public static void ValidateParticipantIdsDiffer(string participantId1, string participantId2)
|
||||
{
|
||||
if (participantId1.Equals(participantId2))
|
||||
{
|
||||
throw new CryptoException("Both participants are using the same participantId (" + participantId1 + "). This is not allowed. Each participant must use a unique participantId.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ValidateParticipantIdsEqual(string expectedParticipantId, string actualParticipantId)
|
||||
{
|
||||
if (!expectedParticipantId.Equals(actualParticipantId))
|
||||
{
|
||||
throw new CryptoException("Received payload from incorrect partner (" + actualParticipantId + "). Expected to receive payload from " + expectedParticipantId + ".");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ValidateNotNull(object obj, string description)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new ArgumentNullException(description);
|
||||
}
|
||||
}
|
||||
|
||||
public static BigInteger CalculateMacTag(string participantId, string partnerParticipantId, BigInteger gx1, BigInteger gx2, BigInteger gx3, BigInteger gx4, BigInteger keyingMaterial, IDigest digest)
|
||||
{
|
||||
byte[] array = CalculateMacKey(keyingMaterial, digest);
|
||||
HMac hMac = new HMac(digest);
|
||||
hMac.Init(new KeyParameter(array));
|
||||
Arrays.Fill(array, 0);
|
||||
UpdateMac(hMac, "KC_1_U");
|
||||
UpdateMac(hMac, participantId);
|
||||
UpdateMac(hMac, partnerParticipantId);
|
||||
UpdateMac(hMac, gx1);
|
||||
UpdateMac(hMac, gx2);
|
||||
UpdateMac(hMac, gx3);
|
||||
UpdateMac(hMac, gx4);
|
||||
byte[] bytes = MacUtilities.DoFinal(hMac);
|
||||
return new BigInteger(bytes);
|
||||
}
|
||||
|
||||
private static byte[] CalculateMacKey(BigInteger keyingMaterial, IDigest digest)
|
||||
{
|
||||
digest.Reset();
|
||||
UpdateDigest(digest, keyingMaterial);
|
||||
UpdateDigest(digest, "JPAKE_KC");
|
||||
return DigestUtilities.DoFinal(digest);
|
||||
}
|
||||
|
||||
public static void ValidateMacTag(string participantId, string partnerParticipantId, BigInteger gx1, BigInteger gx2, BigInteger gx3, BigInteger gx4, BigInteger keyingMaterial, IDigest digest, BigInteger partnerMacTag)
|
||||
{
|
||||
BigInteger bigInteger = CalculateMacTag(partnerParticipantId, participantId, gx3, gx4, gx1, gx2, keyingMaterial, digest);
|
||||
if (!bigInteger.Equals(partnerMacTag))
|
||||
{
|
||||
throw new CryptoException("Partner MacTag validation failed. Therefore, the password, MAC, or digest algorithm of each participant does not match.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateDigest(IDigest digest, BigInteger bigInteger)
|
||||
{
|
||||
UpdateDigest(digest, BigIntegers.AsUnsignedByteArray(bigInteger));
|
||||
}
|
||||
|
||||
private static void UpdateDigest(IDigest digest, string str)
|
||||
{
|
||||
UpdateDigest(digest, Encoding.UTF8.GetBytes(str));
|
||||
}
|
||||
|
||||
private static void UpdateDigest(IDigest digest, byte[] bytes)
|
||||
{
|
||||
digest.BlockUpdate(bytes, 0, bytes.Length);
|
||||
Arrays.Fill(bytes, 0);
|
||||
}
|
||||
|
||||
private static void UpdateDigestIncludingSize(IDigest digest, BigInteger bigInteger)
|
||||
{
|
||||
UpdateDigestIncludingSize(digest, BigIntegers.AsUnsignedByteArray(bigInteger));
|
||||
}
|
||||
|
||||
private static void UpdateDigestIncludingSize(IDigest digest, string str)
|
||||
{
|
||||
UpdateDigestIncludingSize(digest, Encoding.UTF8.GetBytes(str));
|
||||
}
|
||||
|
||||
private static void UpdateDigestIncludingSize(IDigest digest, byte[] bytes)
|
||||
{
|
||||
digest.BlockUpdate(IntToByteArray(bytes.Length), 0, 4);
|
||||
digest.BlockUpdate(bytes, 0, bytes.Length);
|
||||
Arrays.Fill(bytes, 0);
|
||||
}
|
||||
|
||||
private static void UpdateMac(IMac mac, BigInteger bigInteger)
|
||||
{
|
||||
UpdateMac(mac, BigIntegers.AsUnsignedByteArray(bigInteger));
|
||||
}
|
||||
|
||||
private static void UpdateMac(IMac mac, string str)
|
||||
{
|
||||
UpdateMac(mac, Encoding.UTF8.GetBytes(str));
|
||||
}
|
||||
|
||||
private static void UpdateMac(IMac mac, byte[] bytes)
|
||||
{
|
||||
mac.BlockUpdate(bytes, 0, bytes.Length);
|
||||
Arrays.Fill(bytes, 0);
|
||||
}
|
||||
|
||||
private static byte[] IntToByteArray(int value)
|
||||
{
|
||||
return Pack.UInt32_To_BE((uint)value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.Kdf;
|
||||
|
||||
public class ConcatenationKdfGenerator : IDerivationFunction
|
||||
{
|
||||
private readonly IDigest mDigest;
|
||||
|
||||
private byte[] mShared;
|
||||
|
||||
private byte[] mOtherInfo;
|
||||
|
||||
private int mHLen;
|
||||
|
||||
public virtual IDigest Digest => mDigest;
|
||||
|
||||
public ConcatenationKdfGenerator(IDigest digest)
|
||||
{
|
||||
mDigest = digest;
|
||||
mHLen = digest.GetDigestSize();
|
||||
}
|
||||
|
||||
public virtual void Init(IDerivationParameters param)
|
||||
{
|
||||
if (!(param is KdfParameters))
|
||||
{
|
||||
throw new ArgumentException("KDF parameters required for ConcatenationKdfGenerator");
|
||||
}
|
||||
KdfParameters kdfParameters = (KdfParameters)param;
|
||||
mShared = kdfParameters.GetSharedSecret();
|
||||
mOtherInfo = kdfParameters.GetIV();
|
||||
}
|
||||
|
||||
public virtual int GenerateBytes(byte[] outBytes, int outOff, int len)
|
||||
{
|
||||
if (outBytes.Length - len < outOff)
|
||||
{
|
||||
throw new DataLengthException("output buffer too small");
|
||||
}
|
||||
byte[] array = new byte[mHLen];
|
||||
byte[] array2 = new byte[4];
|
||||
uint n = 1u;
|
||||
int num = 0;
|
||||
mDigest.Reset();
|
||||
if (len > mHLen)
|
||||
{
|
||||
do
|
||||
{
|
||||
Pack.UInt32_To_BE(n, array2);
|
||||
mDigest.BlockUpdate(array2, 0, array2.Length);
|
||||
mDigest.BlockUpdate(mShared, 0, mShared.Length);
|
||||
mDigest.BlockUpdate(mOtherInfo, 0, mOtherInfo.Length);
|
||||
mDigest.DoFinal(array, 0);
|
||||
Array.Copy(array, 0, outBytes, outOff + num, mHLen);
|
||||
num += mHLen;
|
||||
}
|
||||
while (n++ < len / mHLen);
|
||||
}
|
||||
if (num < len)
|
||||
{
|
||||
Pack.UInt32_To_BE(n, array2);
|
||||
mDigest.BlockUpdate(array2, 0, array2.Length);
|
||||
mDigest.BlockUpdate(mShared, 0, mShared.Length);
|
||||
mDigest.BlockUpdate(mOtherInfo, 0, mOtherInfo.Length);
|
||||
mDigest.DoFinal(array, 0);
|
||||
Array.Copy(array, 0, outBytes, outOff + num, len - num);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.Kdf;
|
||||
|
||||
public class DHKdfParameters : IDerivationParameters
|
||||
{
|
||||
private readonly DerObjectIdentifier algorithm;
|
||||
|
||||
private readonly int keySize;
|
||||
|
||||
private readonly byte[] z;
|
||||
|
||||
private readonly byte[] extraInfo;
|
||||
|
||||
public DerObjectIdentifier Algorithm => algorithm;
|
||||
|
||||
public int KeySize => keySize;
|
||||
|
||||
public DHKdfParameters(DerObjectIdentifier algorithm, int keySize, byte[] z)
|
||||
: this(algorithm, keySize, z, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DHKdfParameters(DerObjectIdentifier algorithm, int keySize, byte[] z, byte[] extraInfo)
|
||||
{
|
||||
this.algorithm = algorithm;
|
||||
this.keySize = keySize;
|
||||
this.z = z;
|
||||
this.extraInfo = extraInfo;
|
||||
}
|
||||
|
||||
public byte[] GetZ()
|
||||
{
|
||||
return z;
|
||||
}
|
||||
|
||||
public byte[] GetExtraInfo()
|
||||
{
|
||||
return extraInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.Kdf;
|
||||
|
||||
public class DHKekGenerator : IDerivationFunction
|
||||
{
|
||||
private readonly IDigest digest;
|
||||
|
||||
private DerObjectIdentifier algorithm;
|
||||
|
||||
private int keySize;
|
||||
|
||||
private byte[] z;
|
||||
|
||||
private byte[] partyAInfo;
|
||||
|
||||
public virtual IDigest Digest => digest;
|
||||
|
||||
public DHKekGenerator(IDigest digest)
|
||||
{
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public virtual void Init(IDerivationParameters param)
|
||||
{
|
||||
DHKdfParameters dHKdfParameters = (DHKdfParameters)param;
|
||||
algorithm = dHKdfParameters.Algorithm;
|
||||
keySize = dHKdfParameters.KeySize;
|
||||
z = dHKdfParameters.GetZ();
|
||||
partyAInfo = dHKdfParameters.GetExtraInfo();
|
||||
}
|
||||
|
||||
public virtual int GenerateBytes(byte[] outBytes, int outOff, int len)
|
||||
{
|
||||
if (outBytes.Length - len < outOff)
|
||||
{
|
||||
throw new DataLengthException("output buffer too small");
|
||||
}
|
||||
long num = len;
|
||||
int digestSize = digest.GetDigestSize();
|
||||
if (num > 8589934591L)
|
||||
{
|
||||
throw new ArgumentException("Output length too large");
|
||||
}
|
||||
int num2 = (int)((num + digestSize - 1) / digestSize);
|
||||
byte[] array = new byte[digest.GetDigestSize()];
|
||||
uint num3 = 1u;
|
||||
for (int i = 0; i < num2; i++)
|
||||
{
|
||||
digest.BlockUpdate(z, 0, z.Length);
|
||||
DerSequence derSequence = new DerSequence(algorithm, new DerOctetString(Pack.UInt32_To_BE(num3)));
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(derSequence);
|
||||
if (partyAInfo != null)
|
||||
{
|
||||
asn1EncodableVector.Add(new DerTaggedObject(explicitly: true, 0, new DerOctetString(partyAInfo)));
|
||||
}
|
||||
asn1EncodableVector.Add(new DerTaggedObject(explicitly: true, 2, new DerOctetString(Pack.UInt32_To_BE((uint)keySize))));
|
||||
byte[] derEncoded = new DerSequence(asn1EncodableVector).GetDerEncoded();
|
||||
digest.BlockUpdate(derEncoded, 0, derEncoded.Length);
|
||||
digest.DoFinal(array, 0);
|
||||
if (len > digestSize)
|
||||
{
|
||||
Array.Copy(array, 0, outBytes, outOff, digestSize);
|
||||
outOff += digestSize;
|
||||
len -= digestSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(array, 0, outBytes, outOff, len);
|
||||
}
|
||||
num3++;
|
||||
}
|
||||
digest.Reset();
|
||||
return (int)num;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto.Generators;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.Kdf;
|
||||
|
||||
public class ECDHKekGenerator : IDerivationFunction
|
||||
{
|
||||
private readonly IDerivationFunction kdf;
|
||||
|
||||
private DerObjectIdentifier algorithm;
|
||||
|
||||
private int keySize;
|
||||
|
||||
private byte[] z;
|
||||
|
||||
public virtual IDigest Digest => kdf.Digest;
|
||||
|
||||
public ECDHKekGenerator(IDigest digest)
|
||||
{
|
||||
kdf = new Kdf2BytesGenerator(digest);
|
||||
}
|
||||
|
||||
public virtual void Init(IDerivationParameters param)
|
||||
{
|
||||
DHKdfParameters dHKdfParameters = (DHKdfParameters)param;
|
||||
algorithm = dHKdfParameters.Algorithm;
|
||||
keySize = dHKdfParameters.KeySize;
|
||||
z = dHKdfParameters.GetZ();
|
||||
}
|
||||
|
||||
public virtual int GenerateBytes(byte[] outBytes, int outOff, int len)
|
||||
{
|
||||
DerSequence derSequence = new DerSequence(new AlgorithmIdentifier(algorithm, DerNull.Instance), new DerTaggedObject(explicitly: true, 2, new DerOctetString(Pack.UInt32_To_BE((uint)keySize))));
|
||||
kdf.Init(new KdfParameters(z, derSequence.GetDerEncoded()));
|
||||
return kdf.GenerateBytes(outBytes, outOff, len);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Digests;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Math.EC;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public class SM2KeyExchange
|
||||
{
|
||||
private readonly IDigest mDigest;
|
||||
|
||||
private byte[] mUserID;
|
||||
|
||||
private ECPrivateKeyParameters mStaticKey;
|
||||
|
||||
private ECPoint mStaticPubPoint;
|
||||
|
||||
private ECPoint mEphemeralPubPoint;
|
||||
|
||||
private ECDomainParameters mECParams;
|
||||
|
||||
private int mW;
|
||||
|
||||
private ECPrivateKeyParameters mEphemeralKey;
|
||||
|
||||
private bool mInitiator;
|
||||
|
||||
public SM2KeyExchange()
|
||||
: this(new SM3Digest())
|
||||
{
|
||||
}
|
||||
|
||||
public SM2KeyExchange(IDigest digest)
|
||||
{
|
||||
mDigest = digest;
|
||||
}
|
||||
|
||||
public virtual void Init(ICipherParameters privParam)
|
||||
{
|
||||
SM2KeyExchangePrivateParameters sM2KeyExchangePrivateParameters;
|
||||
if (privParam is ParametersWithID)
|
||||
{
|
||||
sM2KeyExchangePrivateParameters = (SM2KeyExchangePrivateParameters)((ParametersWithID)privParam).Parameters;
|
||||
mUserID = ((ParametersWithID)privParam).GetID();
|
||||
}
|
||||
else
|
||||
{
|
||||
sM2KeyExchangePrivateParameters = (SM2KeyExchangePrivateParameters)privParam;
|
||||
mUserID = new byte[0];
|
||||
}
|
||||
mInitiator = sM2KeyExchangePrivateParameters.IsInitiator;
|
||||
mStaticKey = sM2KeyExchangePrivateParameters.StaticPrivateKey;
|
||||
mEphemeralKey = sM2KeyExchangePrivateParameters.EphemeralPrivateKey;
|
||||
mECParams = mStaticKey.Parameters;
|
||||
mStaticPubPoint = sM2KeyExchangePrivateParameters.StaticPublicPoint;
|
||||
mEphemeralPubPoint = sM2KeyExchangePrivateParameters.EphemeralPublicPoint;
|
||||
mW = mECParams.Curve.FieldSize / 2 - 1;
|
||||
}
|
||||
|
||||
public virtual byte[] CalculateKey(int kLen, ICipherParameters pubParam)
|
||||
{
|
||||
SM2KeyExchangePublicParameters sM2KeyExchangePublicParameters;
|
||||
byte[] userID;
|
||||
if (pubParam is ParametersWithID)
|
||||
{
|
||||
sM2KeyExchangePublicParameters = (SM2KeyExchangePublicParameters)((ParametersWithID)pubParam).Parameters;
|
||||
userID = ((ParametersWithID)pubParam).GetID();
|
||||
}
|
||||
else
|
||||
{
|
||||
sM2KeyExchangePublicParameters = (SM2KeyExchangePublicParameters)pubParam;
|
||||
userID = new byte[0];
|
||||
}
|
||||
byte[] z = GetZ(mDigest, mUserID, mStaticPubPoint);
|
||||
byte[] z2 = GetZ(mDigest, userID, sM2KeyExchangePublicParameters.StaticPublicKey.Q);
|
||||
ECPoint u = CalculateU(sM2KeyExchangePublicParameters);
|
||||
if (mInitiator)
|
||||
{
|
||||
return Kdf(u, z, z2, kLen);
|
||||
}
|
||||
return Kdf(u, z2, z, kLen);
|
||||
}
|
||||
|
||||
public virtual byte[][] CalculateKeyWithConfirmation(int kLen, byte[] confirmationTag, ICipherParameters pubParam)
|
||||
{
|
||||
SM2KeyExchangePublicParameters sM2KeyExchangePublicParameters;
|
||||
byte[] userID;
|
||||
if (pubParam is ParametersWithID)
|
||||
{
|
||||
sM2KeyExchangePublicParameters = (SM2KeyExchangePublicParameters)((ParametersWithID)pubParam).Parameters;
|
||||
userID = ((ParametersWithID)pubParam).GetID();
|
||||
}
|
||||
else
|
||||
{
|
||||
sM2KeyExchangePublicParameters = (SM2KeyExchangePublicParameters)pubParam;
|
||||
userID = new byte[0];
|
||||
}
|
||||
if (mInitiator && confirmationTag == null)
|
||||
{
|
||||
throw new ArgumentException("if initiating, confirmationTag must be set");
|
||||
}
|
||||
byte[] z = GetZ(mDigest, mUserID, mStaticPubPoint);
|
||||
byte[] z2 = GetZ(mDigest, userID, sM2KeyExchangePublicParameters.StaticPublicKey.Q);
|
||||
ECPoint u = CalculateU(sM2KeyExchangePublicParameters);
|
||||
byte[] array;
|
||||
if (mInitiator)
|
||||
{
|
||||
array = Kdf(u, z, z2, kLen);
|
||||
byte[] inner = CalculateInnerHash(mDigest, u, z, z2, mEphemeralPubPoint, sM2KeyExchangePublicParameters.EphemeralPublicKey.Q);
|
||||
byte[] a = S1(mDigest, u, inner);
|
||||
if (!Arrays.ConstantTimeAreEqual(a, confirmationTag))
|
||||
{
|
||||
throw new InvalidOperationException("confirmation tag mismatch");
|
||||
}
|
||||
return new byte[2][]
|
||||
{
|
||||
array,
|
||||
S2(mDigest, u, inner)
|
||||
};
|
||||
}
|
||||
array = Kdf(u, z2, z, kLen);
|
||||
byte[] inner2 = CalculateInnerHash(mDigest, u, z2, z, sM2KeyExchangePublicParameters.EphemeralPublicKey.Q, mEphemeralPubPoint);
|
||||
return new byte[3][]
|
||||
{
|
||||
array,
|
||||
S1(mDigest, u, inner2),
|
||||
S2(mDigest, u, inner2)
|
||||
};
|
||||
}
|
||||
|
||||
protected virtual ECPoint CalculateU(SM2KeyExchangePublicParameters otherPub)
|
||||
{
|
||||
ECDomainParameters parameters = mStaticKey.Parameters;
|
||||
ECPoint p = ECAlgorithms.CleanPoint(parameters.Curve, otherPub.StaticPublicKey.Q);
|
||||
ECPoint eCPoint = ECAlgorithms.CleanPoint(parameters.Curve, otherPub.EphemeralPublicKey.Q);
|
||||
BigInteger bigInteger = Reduce(mEphemeralPubPoint.AffineXCoord.ToBigInteger());
|
||||
BigInteger val = Reduce(eCPoint.AffineXCoord.ToBigInteger());
|
||||
BigInteger val2 = mStaticKey.D.Add(bigInteger.Multiply(mEphemeralKey.D));
|
||||
BigInteger bigInteger2 = mECParams.H.Multiply(val2).Mod(mECParams.N);
|
||||
BigInteger b = bigInteger2.Multiply(val).Mod(mECParams.N);
|
||||
return ECAlgorithms.SumOfTwoMultiplies(p, bigInteger2, eCPoint, b).Normalize();
|
||||
}
|
||||
|
||||
protected virtual byte[] Kdf(ECPoint u, byte[] za, byte[] zb, int klen)
|
||||
{
|
||||
int digestSize = mDigest.GetDigestSize();
|
||||
byte[] array = new byte[System.Math.Max(4, digestSize)];
|
||||
byte[] array2 = new byte[(klen + 7) / 8];
|
||||
int i = 0;
|
||||
IMemoable memoable = mDigest as IMemoable;
|
||||
IMemoable other = null;
|
||||
if (memoable != null)
|
||||
{
|
||||
AddFieldElement(mDigest, u.AffineXCoord);
|
||||
AddFieldElement(mDigest, u.AffineYCoord);
|
||||
mDigest.BlockUpdate(za, 0, za.Length);
|
||||
mDigest.BlockUpdate(zb, 0, zb.Length);
|
||||
other = memoable.Copy();
|
||||
}
|
||||
uint num = 0u;
|
||||
int num2;
|
||||
for (; i < array2.Length; i += num2)
|
||||
{
|
||||
if (memoable != null)
|
||||
{
|
||||
memoable.Reset(other);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddFieldElement(mDigest, u.AffineXCoord);
|
||||
AddFieldElement(mDigest, u.AffineYCoord);
|
||||
mDigest.BlockUpdate(za, 0, za.Length);
|
||||
mDigest.BlockUpdate(zb, 0, zb.Length);
|
||||
}
|
||||
Pack.UInt32_To_BE(++num, array, 0);
|
||||
mDigest.BlockUpdate(array, 0, 4);
|
||||
mDigest.DoFinal(array, 0);
|
||||
num2 = System.Math.Min(digestSize, array2.Length - i);
|
||||
Array.Copy(array, 0, array2, i, num2);
|
||||
}
|
||||
return array2;
|
||||
}
|
||||
|
||||
private BigInteger Reduce(BigInteger x)
|
||||
{
|
||||
return x.And(BigInteger.One.ShiftLeft(mW).Subtract(BigInteger.One)).SetBit(mW);
|
||||
}
|
||||
|
||||
private byte[] S1(IDigest digest, ECPoint u, byte[] inner)
|
||||
{
|
||||
digest.Update(2);
|
||||
AddFieldElement(digest, u.AffineYCoord);
|
||||
digest.BlockUpdate(inner, 0, inner.Length);
|
||||
return DigestUtilities.DoFinal(digest);
|
||||
}
|
||||
|
||||
private byte[] CalculateInnerHash(IDigest digest, ECPoint u, byte[] za, byte[] zb, ECPoint p1, ECPoint p2)
|
||||
{
|
||||
AddFieldElement(digest, u.AffineXCoord);
|
||||
digest.BlockUpdate(za, 0, za.Length);
|
||||
digest.BlockUpdate(zb, 0, zb.Length);
|
||||
AddFieldElement(digest, p1.AffineXCoord);
|
||||
AddFieldElement(digest, p1.AffineYCoord);
|
||||
AddFieldElement(digest, p2.AffineXCoord);
|
||||
AddFieldElement(digest, p2.AffineYCoord);
|
||||
return DigestUtilities.DoFinal(digest);
|
||||
}
|
||||
|
||||
private byte[] S2(IDigest digest, ECPoint u, byte[] inner)
|
||||
{
|
||||
digest.Update(3);
|
||||
AddFieldElement(digest, u.AffineYCoord);
|
||||
digest.BlockUpdate(inner, 0, inner.Length);
|
||||
return DigestUtilities.DoFinal(digest);
|
||||
}
|
||||
|
||||
private byte[] GetZ(IDigest digest, byte[] userID, ECPoint pubPoint)
|
||||
{
|
||||
AddUserID(digest, userID);
|
||||
AddFieldElement(digest, mECParams.Curve.A);
|
||||
AddFieldElement(digest, mECParams.Curve.B);
|
||||
AddFieldElement(digest, mECParams.G.AffineXCoord);
|
||||
AddFieldElement(digest, mECParams.G.AffineYCoord);
|
||||
AddFieldElement(digest, pubPoint.AffineXCoord);
|
||||
AddFieldElement(digest, pubPoint.AffineYCoord);
|
||||
return DigestUtilities.DoFinal(digest);
|
||||
}
|
||||
|
||||
private void AddUserID(IDigest digest, byte[] userID)
|
||||
{
|
||||
uint num = (uint)(userID.Length * 8);
|
||||
digest.Update((byte)(num >> 8));
|
||||
digest.Update((byte)num);
|
||||
digest.BlockUpdate(userID, 0, userID.Length);
|
||||
}
|
||||
|
||||
private void AddFieldElement(IDigest digest, ECFieldElement v)
|
||||
{
|
||||
byte[] encoded = v.GetEncoded();
|
||||
digest.BlockUpdate(encoded, 0, encoded.Length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.Srp;
|
||||
|
||||
public class Srp6Client
|
||||
{
|
||||
protected BigInteger N;
|
||||
|
||||
protected BigInteger g;
|
||||
|
||||
protected BigInteger privA;
|
||||
|
||||
protected BigInteger pubA;
|
||||
|
||||
protected BigInteger B;
|
||||
|
||||
protected BigInteger x;
|
||||
|
||||
protected BigInteger u;
|
||||
|
||||
protected BigInteger S;
|
||||
|
||||
protected BigInteger M1;
|
||||
|
||||
protected BigInteger M2;
|
||||
|
||||
protected BigInteger Key;
|
||||
|
||||
protected IDigest digest;
|
||||
|
||||
protected SecureRandom random;
|
||||
|
||||
public virtual void Init(BigInteger N, BigInteger g, IDigest digest, SecureRandom random)
|
||||
{
|
||||
this.N = N;
|
||||
this.g = g;
|
||||
this.digest = digest;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public virtual void Init(Srp6GroupParameters group, IDigest digest, SecureRandom random)
|
||||
{
|
||||
Init(group.N, group.G, digest, random);
|
||||
}
|
||||
|
||||
public virtual BigInteger GenerateClientCredentials(byte[] salt, byte[] identity, byte[] password)
|
||||
{
|
||||
x = Srp6Utilities.CalculateX(digest, N, salt, identity, password);
|
||||
privA = SelectPrivateValue();
|
||||
pubA = g.ModPow(privA, N);
|
||||
return pubA;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateSecret(BigInteger serverB)
|
||||
{
|
||||
B = Srp6Utilities.ValidatePublicValue(N, serverB);
|
||||
u = Srp6Utilities.CalculateU(digest, N, pubA, B);
|
||||
S = CalculateS();
|
||||
return S;
|
||||
}
|
||||
|
||||
protected virtual BigInteger SelectPrivateValue()
|
||||
{
|
||||
return Srp6Utilities.GeneratePrivateValue(digest, N, g, random);
|
||||
}
|
||||
|
||||
private BigInteger CalculateS()
|
||||
{
|
||||
BigInteger val = Srp6Utilities.CalculateK(digest, N, g);
|
||||
BigInteger e = u.Multiply(x).Add(privA);
|
||||
BigInteger n = g.ModPow(x, N).Multiply(val).Mod(N);
|
||||
return B.Subtract(n).Mod(N).ModPow(e, N);
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateClientEvidenceMessage()
|
||||
{
|
||||
if (pubA == null || B == null || S == null)
|
||||
{
|
||||
throw new CryptoException("Impossible to compute M1: some data are missing from the previous operations (A,B,S)");
|
||||
}
|
||||
M1 = Srp6Utilities.CalculateM1(digest, N, pubA, B, S);
|
||||
return M1;
|
||||
}
|
||||
|
||||
public virtual bool VerifyServerEvidenceMessage(BigInteger serverM2)
|
||||
{
|
||||
if (pubA == null || M1 == null || S == null)
|
||||
{
|
||||
throw new CryptoException("Impossible to compute and verify M2: some data are missing from the previous operations (A,M1,S)");
|
||||
}
|
||||
BigInteger bigInteger = Srp6Utilities.CalculateM2(digest, N, pubA, M1, S);
|
||||
if (bigInteger.Equals(serverM2))
|
||||
{
|
||||
M2 = serverM2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateSessionKey()
|
||||
{
|
||||
if (S == null || M1 == null || M2 == null)
|
||||
{
|
||||
throw new CryptoException("Impossible to compute Key: some data are missing from the previous operations (S,M1,M2)");
|
||||
}
|
||||
Key = Srp6Utilities.CalculateKey(digest, N, S);
|
||||
return Key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.Srp;
|
||||
|
||||
public class Srp6Server
|
||||
{
|
||||
protected BigInteger N;
|
||||
|
||||
protected BigInteger g;
|
||||
|
||||
protected BigInteger v;
|
||||
|
||||
protected SecureRandom random;
|
||||
|
||||
protected IDigest digest;
|
||||
|
||||
protected BigInteger A;
|
||||
|
||||
protected BigInteger privB;
|
||||
|
||||
protected BigInteger pubB;
|
||||
|
||||
protected BigInteger u;
|
||||
|
||||
protected BigInteger S;
|
||||
|
||||
protected BigInteger M1;
|
||||
|
||||
protected BigInteger M2;
|
||||
|
||||
protected BigInteger Key;
|
||||
|
||||
public virtual void Init(BigInteger N, BigInteger g, BigInteger v, IDigest digest, SecureRandom random)
|
||||
{
|
||||
this.N = N;
|
||||
this.g = g;
|
||||
this.v = v;
|
||||
this.random = random;
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public virtual void Init(Srp6GroupParameters group, BigInteger v, IDigest digest, SecureRandom random)
|
||||
{
|
||||
Init(group.N, group.G, v, digest, random);
|
||||
}
|
||||
|
||||
public virtual BigInteger GenerateServerCredentials()
|
||||
{
|
||||
BigInteger bigInteger = Srp6Utilities.CalculateK(digest, N, g);
|
||||
privB = SelectPrivateValue();
|
||||
pubB = bigInteger.Multiply(v).Mod(N).Add(g.ModPow(privB, N))
|
||||
.Mod(N);
|
||||
return pubB;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateSecret(BigInteger clientA)
|
||||
{
|
||||
A = Srp6Utilities.ValidatePublicValue(N, clientA);
|
||||
u = Srp6Utilities.CalculateU(digest, N, A, pubB);
|
||||
S = CalculateS();
|
||||
return S;
|
||||
}
|
||||
|
||||
protected virtual BigInteger SelectPrivateValue()
|
||||
{
|
||||
return Srp6Utilities.GeneratePrivateValue(digest, N, g, random);
|
||||
}
|
||||
|
||||
private BigInteger CalculateS()
|
||||
{
|
||||
return v.ModPow(u, N).Multiply(A).Mod(N)
|
||||
.ModPow(privB, N);
|
||||
}
|
||||
|
||||
public virtual bool VerifyClientEvidenceMessage(BigInteger clientM1)
|
||||
{
|
||||
if (A == null || pubB == null || S == null)
|
||||
{
|
||||
throw new CryptoException("Impossible to compute and verify M1: some data are missing from the previous operations (A,B,S)");
|
||||
}
|
||||
BigInteger bigInteger = Srp6Utilities.CalculateM1(digest, N, A, pubB, S);
|
||||
if (bigInteger.Equals(clientM1))
|
||||
{
|
||||
M1 = clientM1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateServerEvidenceMessage()
|
||||
{
|
||||
if (A == null || M1 == null || S == null)
|
||||
{
|
||||
throw new CryptoException("Impossible to compute M2: some data are missing from the previous operations (A,M1,S)");
|
||||
}
|
||||
M2 = Srp6Utilities.CalculateM2(digest, N, A, M1, S);
|
||||
return M2;
|
||||
}
|
||||
|
||||
public virtual BigInteger CalculateSessionKey()
|
||||
{
|
||||
if (S == null || M1 == null || M2 == null)
|
||||
{
|
||||
throw new CryptoException("Impossible to compute Key: some data are missing from the previous operations (S,M1,M2)");
|
||||
}
|
||||
Key = Srp6Utilities.CalculateKey(digest, N, S);
|
||||
return Key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.Srp;
|
||||
|
||||
public class Srp6StandardGroups
|
||||
{
|
||||
private const string rfc5054_1024_N = "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3";
|
||||
|
||||
private const string rfc5054_1024_g = "02";
|
||||
|
||||
private const string rfc5054_1536_N = "9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB";
|
||||
|
||||
private const string rfc5054_1536_g = "02";
|
||||
|
||||
private const string rfc5054_2048_N = "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73";
|
||||
|
||||
private const string rfc5054_2048_g = "02";
|
||||
|
||||
private const string rfc5054_3072_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
|
||||
|
||||
private const string rfc5054_3072_g = "05";
|
||||
|
||||
private const string rfc5054_4096_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF";
|
||||
|
||||
private const string rfc5054_4096_g = "05";
|
||||
|
||||
private const string rfc5054_6144_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF";
|
||||
|
||||
private const string rfc5054_6144_g = "05";
|
||||
|
||||
private const string rfc5054_8192_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF";
|
||||
|
||||
private const string rfc5054_8192_g = "13";
|
||||
|
||||
public static readonly Srp6GroupParameters rfc5054_1024 = FromNG("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3", "02");
|
||||
|
||||
public static readonly Srp6GroupParameters rfc5054_1536 = FromNG("9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB", "02");
|
||||
|
||||
public static readonly Srp6GroupParameters rfc5054_2048 = FromNG("AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73", "02");
|
||||
|
||||
public static readonly Srp6GroupParameters rfc5054_3072 = FromNG("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", "05");
|
||||
|
||||
public static readonly Srp6GroupParameters rfc5054_4096 = FromNG("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", "05");
|
||||
|
||||
public static readonly Srp6GroupParameters rfc5054_6144 = FromNG("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF", "05");
|
||||
|
||||
public static readonly Srp6GroupParameters rfc5054_8192 = FromNG("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF", "13");
|
||||
|
||||
private static BigInteger FromHex(string hex)
|
||||
{
|
||||
return new BigInteger(1, Hex.Decode(hex));
|
||||
}
|
||||
|
||||
private static Srp6GroupParameters FromNG(string hexN, string hexG)
|
||||
{
|
||||
return new Srp6GroupParameters(FromHex(hexN), FromHex(hexG));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.Srp;
|
||||
|
||||
public class Srp6Utilities
|
||||
{
|
||||
public static BigInteger CalculateK(IDigest digest, BigInteger N, BigInteger g)
|
||||
{
|
||||
return HashPaddedPair(digest, N, N, g);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateU(IDigest digest, BigInteger N, BigInteger A, BigInteger B)
|
||||
{
|
||||
return HashPaddedPair(digest, N, A, B);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateX(IDigest digest, BigInteger N, byte[] salt, byte[] identity, byte[] password)
|
||||
{
|
||||
byte[] array = new byte[digest.GetDigestSize()];
|
||||
digest.BlockUpdate(identity, 0, identity.Length);
|
||||
digest.Update(58);
|
||||
digest.BlockUpdate(password, 0, password.Length);
|
||||
digest.DoFinal(array, 0);
|
||||
digest.BlockUpdate(salt, 0, salt.Length);
|
||||
digest.BlockUpdate(array, 0, array.Length);
|
||||
digest.DoFinal(array, 0);
|
||||
return new BigInteger(1, array);
|
||||
}
|
||||
|
||||
public static BigInteger GeneratePrivateValue(IDigest digest, BigInteger N, BigInteger g, SecureRandom random)
|
||||
{
|
||||
int num = System.Math.Min(256, N.BitLength / 2);
|
||||
BigInteger min = BigInteger.One.ShiftLeft(num - 1);
|
||||
BigInteger max = N.Subtract(BigInteger.One);
|
||||
return BigIntegers.CreateRandomInRange(min, max, random);
|
||||
}
|
||||
|
||||
public static BigInteger ValidatePublicValue(BigInteger N, BigInteger val)
|
||||
{
|
||||
val = val.Mod(N);
|
||||
if (val.Equals(BigInteger.Zero))
|
||||
{
|
||||
throw new CryptoException("Invalid public value: 0");
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public static BigInteger CalculateM1(IDigest digest, BigInteger N, BigInteger A, BigInteger B, BigInteger S)
|
||||
{
|
||||
return HashPaddedTriplet(digest, N, A, B, S);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateM2(IDigest digest, BigInteger N, BigInteger A, BigInteger M1, BigInteger S)
|
||||
{
|
||||
return HashPaddedTriplet(digest, N, A, M1, S);
|
||||
}
|
||||
|
||||
public static BigInteger CalculateKey(IDigest digest, BigInteger N, BigInteger S)
|
||||
{
|
||||
int length = (N.BitLength + 7) / 8;
|
||||
byte[] padded = GetPadded(S, length);
|
||||
digest.BlockUpdate(padded, 0, padded.Length);
|
||||
byte[] array = new byte[digest.GetDigestSize()];
|
||||
digest.DoFinal(array, 0);
|
||||
return new BigInteger(1, array);
|
||||
}
|
||||
|
||||
private static BigInteger HashPaddedTriplet(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2, BigInteger n3)
|
||||
{
|
||||
int length = (N.BitLength + 7) / 8;
|
||||
byte[] padded = GetPadded(n1, length);
|
||||
byte[] padded2 = GetPadded(n2, length);
|
||||
byte[] padded3 = GetPadded(n3, length);
|
||||
digest.BlockUpdate(padded, 0, padded.Length);
|
||||
digest.BlockUpdate(padded2, 0, padded2.Length);
|
||||
digest.BlockUpdate(padded3, 0, padded3.Length);
|
||||
byte[] array = new byte[digest.GetDigestSize()];
|
||||
digest.DoFinal(array, 0);
|
||||
return new BigInteger(1, array);
|
||||
}
|
||||
|
||||
private static BigInteger HashPaddedPair(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2)
|
||||
{
|
||||
int length = (N.BitLength + 7) / 8;
|
||||
byte[] padded = GetPadded(n1, length);
|
||||
byte[] padded2 = GetPadded(n2, length);
|
||||
digest.BlockUpdate(padded, 0, padded.Length);
|
||||
digest.BlockUpdate(padded2, 0, padded2.Length);
|
||||
byte[] array = new byte[digest.GetDigestSize()];
|
||||
digest.DoFinal(array, 0);
|
||||
return new BigInteger(1, array);
|
||||
}
|
||||
|
||||
private static byte[] GetPadded(BigInteger n, int length)
|
||||
{
|
||||
byte[] array = BigIntegers.AsUnsignedByteArray(n);
|
||||
if (array.Length < length)
|
||||
{
|
||||
byte[] array2 = new byte[length];
|
||||
Array.Copy(array, 0, array2, length - array.Length, array.Length);
|
||||
array = array2;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement.Srp;
|
||||
|
||||
public class Srp6VerifierGenerator
|
||||
{
|
||||
protected BigInteger N;
|
||||
|
||||
protected BigInteger g;
|
||||
|
||||
protected IDigest digest;
|
||||
|
||||
public virtual void Init(BigInteger N, BigInteger g, IDigest digest)
|
||||
{
|
||||
this.N = N;
|
||||
this.g = g;
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public virtual void Init(Srp6GroupParameters group, IDigest digest)
|
||||
{
|
||||
Init(group.N, group.G, digest);
|
||||
}
|
||||
|
||||
public virtual BigInteger GenerateVerifier(byte[] salt, byte[] identity, byte[] password)
|
||||
{
|
||||
BigInteger e = Srp6Utilities.CalculateX(digest, N, salt, identity, password);
|
||||
return g.ModPow(e, N);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public sealed class X25519Agreement : IRawAgreement
|
||||
{
|
||||
private X25519PrivateKeyParameters privateKey;
|
||||
|
||||
public int AgreementSize => X25519PrivateKeyParameters.SecretSize;
|
||||
|
||||
public void Init(ICipherParameters parameters)
|
||||
{
|
||||
privateKey = (X25519PrivateKeyParameters)parameters;
|
||||
}
|
||||
|
||||
public void CalculateAgreement(ICipherParameters publicKey, byte[] buf, int off)
|
||||
{
|
||||
privateKey.GenerateSecret((X25519PublicKeyParameters)publicKey, buf, off);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Agreement;
|
||||
|
||||
public sealed class X448Agreement : IRawAgreement
|
||||
{
|
||||
private X448PrivateKeyParameters privateKey;
|
||||
|
||||
public int AgreementSize => X448PrivateKeyParameters.SecretSize;
|
||||
|
||||
public void Init(ICipherParameters parameters)
|
||||
{
|
||||
privateKey = (X448PrivateKeyParameters)parameters;
|
||||
}
|
||||
|
||||
public void CalculateAgreement(ICipherParameters publicKey, byte[] buf, int off)
|
||||
{
|
||||
privateKey.GenerateSecret((X448PublicKeyParameters)publicKey, buf, off);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
public class AsymmetricCipherKeyPair
|
||||
{
|
||||
private readonly AsymmetricKeyParameter publicParameter;
|
||||
|
||||
private readonly AsymmetricKeyParameter privateParameter;
|
||||
|
||||
public AsymmetricKeyParameter Public => publicParameter;
|
||||
|
||||
public AsymmetricKeyParameter Private => privateParameter;
|
||||
|
||||
public AsymmetricCipherKeyPair(AsymmetricKeyParameter publicParameter, AsymmetricKeyParameter privateParameter)
|
||||
{
|
||||
if (publicParameter.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Expected a public key", "publicParameter");
|
||||
}
|
||||
if (!privateParameter.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Expected a private key", "privateParameter");
|
||||
}
|
||||
this.publicParameter = publicParameter;
|
||||
this.privateParameter = privateParameter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
public abstract class AsymmetricKeyParameter : ICipherParameters
|
||||
{
|
||||
private readonly bool privateKey;
|
||||
|
||||
public bool IsPrivate => privateKey;
|
||||
|
||||
protected AsymmetricKeyParameter(bool privateKey)
|
||||
{
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is AsymmetricKeyParameter other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Equals(other);
|
||||
}
|
||||
|
||||
protected bool Equals(AsymmetricKeyParameter other)
|
||||
{
|
||||
return privateKey == other.privateKey;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
bool flag = privateKey;
|
||||
return flag.GetHashCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Modes;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
public class BufferedAeadBlockCipher : BufferedCipherBase
|
||||
{
|
||||
private readonly IAeadBlockCipher cipher;
|
||||
|
||||
public override string AlgorithmName => cipher.AlgorithmName;
|
||||
|
||||
public BufferedAeadBlockCipher(IAeadBlockCipher cipher)
|
||||
{
|
||||
if (cipher == null)
|
||||
{
|
||||
throw new ArgumentNullException("cipher");
|
||||
}
|
||||
this.cipher = cipher;
|
||||
}
|
||||
|
||||
public override void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
parameters = ((ParametersWithRandom)parameters).Parameters;
|
||||
}
|
||||
cipher.Init(forEncryption, parameters);
|
||||
}
|
||||
|
||||
public override int GetBlockSize()
|
||||
{
|
||||
return cipher.GetBlockSize();
|
||||
}
|
||||
|
||||
public override int GetUpdateOutputSize(int length)
|
||||
{
|
||||
return cipher.GetUpdateOutputSize(length);
|
||||
}
|
||||
|
||||
public override int GetOutputSize(int length)
|
||||
{
|
||||
return cipher.GetOutputSize(length);
|
||||
}
|
||||
|
||||
public override int ProcessByte(byte input, byte[] output, int outOff)
|
||||
{
|
||||
return cipher.ProcessByte(input, output, outOff);
|
||||
}
|
||||
|
||||
public override byte[] ProcessByte(byte input)
|
||||
{
|
||||
int updateOutputSize = GetUpdateOutputSize(1);
|
||||
byte[] array = ((updateOutputSize > 0) ? new byte[updateOutputSize] : null);
|
||||
int num = ProcessByte(input, array, 0);
|
||||
if (updateOutputSize > 0 && num < updateOutputSize)
|
||||
{
|
||||
byte[] array2 = new byte[num];
|
||||
Array.Copy(array, 0, array2, 0, num);
|
||||
array = array2;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public override byte[] ProcessBytes(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (input == null)
|
||||
{
|
||||
throw new ArgumentNullException("input");
|
||||
}
|
||||
if (length < 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int updateOutputSize = GetUpdateOutputSize(length);
|
||||
byte[] array = ((updateOutputSize > 0) ? new byte[updateOutputSize] : null);
|
||||
int num = ProcessBytes(input, inOff, length, array, 0);
|
||||
if (updateOutputSize > 0 && num < updateOutputSize)
|
||||
{
|
||||
byte[] array2 = new byte[num];
|
||||
Array.Copy(array, 0, array2, 0, num);
|
||||
array = array2;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public override int ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff)
|
||||
{
|
||||
return cipher.ProcessBytes(input, inOff, length, output, outOff);
|
||||
}
|
||||
|
||||
public override byte[] DoFinal()
|
||||
{
|
||||
byte[] array = new byte[GetOutputSize(0)];
|
||||
int num = DoFinal(array, 0);
|
||||
if (num < array.Length)
|
||||
{
|
||||
byte[] array2 = new byte[num];
|
||||
Array.Copy(array, 0, array2, 0, num);
|
||||
array = array2;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public override byte[] DoFinal(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (input == null)
|
||||
{
|
||||
throw new ArgumentNullException("input");
|
||||
}
|
||||
byte[] array = new byte[GetOutputSize(inLen)];
|
||||
int num = ((inLen > 0) ? ProcessBytes(input, inOff, inLen, array, 0) : 0);
|
||||
num += DoFinal(array, num);
|
||||
if (num < array.Length)
|
||||
{
|
||||
byte[] array2 = new byte[num];
|
||||
Array.Copy(array, 0, array2, 0, num);
|
||||
array = array2;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
return cipher.DoFinal(output, outOff);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
cipher.Reset();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
public class BufferedAsymmetricBlockCipher : BufferedCipherBase
|
||||
{
|
||||
private readonly IAsymmetricBlockCipher cipher;
|
||||
|
||||
private byte[] buffer;
|
||||
|
||||
private int bufOff;
|
||||
|
||||
public override string AlgorithmName => cipher.AlgorithmName;
|
||||
|
||||
public BufferedAsymmetricBlockCipher(IAsymmetricBlockCipher cipher)
|
||||
{
|
||||
this.cipher = cipher;
|
||||
}
|
||||
|
||||
internal int GetBufferPosition()
|
||||
{
|
||||
return bufOff;
|
||||
}
|
||||
|
||||
public override int GetBlockSize()
|
||||
{
|
||||
return cipher.GetInputBlockSize();
|
||||
}
|
||||
|
||||
public override int GetOutputSize(int length)
|
||||
{
|
||||
return cipher.GetOutputBlockSize();
|
||||
}
|
||||
|
||||
public override int GetUpdateOutputSize(int length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
Reset();
|
||||
cipher.Init(forEncryption, parameters);
|
||||
buffer = new byte[cipher.GetInputBlockSize() + (forEncryption ? 1 : 0)];
|
||||
bufOff = 0;
|
||||
}
|
||||
|
||||
public override byte[] ProcessByte(byte input)
|
||||
{
|
||||
if (bufOff >= buffer.Length)
|
||||
{
|
||||
throw new DataLengthException("attempt to process message to long for cipher");
|
||||
}
|
||||
buffer[bufOff++] = input;
|
||||
return null;
|
||||
}
|
||||
|
||||
public override byte[] ProcessBytes(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (length < 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (input == null)
|
||||
{
|
||||
throw new ArgumentNullException("input");
|
||||
}
|
||||
if (bufOff + length > buffer.Length)
|
||||
{
|
||||
throw new DataLengthException("attempt to process message to long for cipher");
|
||||
}
|
||||
Array.Copy(input, inOff, buffer, bufOff, length);
|
||||
bufOff += length;
|
||||
return null;
|
||||
}
|
||||
|
||||
public override byte[] DoFinal()
|
||||
{
|
||||
byte[] result = ((bufOff > 0) ? cipher.ProcessBlock(buffer, 0, bufOff) : BufferedCipherBase.EmptyBuffer);
|
||||
Reset();
|
||||
return result;
|
||||
}
|
||||
|
||||
public override byte[] DoFinal(byte[] input, int inOff, int length)
|
||||
{
|
||||
ProcessBytes(input, inOff, length);
|
||||
return DoFinal();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
if (buffer != null)
|
||||
{
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
bufOff = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
public class BufferedBlockCipher : BufferedCipherBase
|
||||
{
|
||||
internal byte[] buf;
|
||||
|
||||
internal int bufOff;
|
||||
|
||||
internal bool forEncryption;
|
||||
|
||||
internal IBlockCipher cipher;
|
||||
|
||||
public override string AlgorithmName => cipher.AlgorithmName;
|
||||
|
||||
protected BufferedBlockCipher()
|
||||
{
|
||||
}
|
||||
|
||||
public BufferedBlockCipher(IBlockCipher cipher)
|
||||
{
|
||||
if (cipher == null)
|
||||
{
|
||||
throw new ArgumentNullException("cipher");
|
||||
}
|
||||
this.cipher = cipher;
|
||||
buf = new byte[cipher.GetBlockSize()];
|
||||
bufOff = 0;
|
||||
}
|
||||
|
||||
public override void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
this.forEncryption = forEncryption;
|
||||
if (parameters is ParametersWithRandom parametersWithRandom)
|
||||
{
|
||||
parameters = parametersWithRandom.Parameters;
|
||||
}
|
||||
Reset();
|
||||
cipher.Init(forEncryption, parameters);
|
||||
}
|
||||
|
||||
public override int GetBlockSize()
|
||||
{
|
||||
return cipher.GetBlockSize();
|
||||
}
|
||||
|
||||
public override int GetUpdateOutputSize(int length)
|
||||
{
|
||||
int num = length + bufOff;
|
||||
int num2 = num % buf.Length;
|
||||
return num - num2;
|
||||
}
|
||||
|
||||
public override int GetOutputSize(int length)
|
||||
{
|
||||
return length + bufOff;
|
||||
}
|
||||
|
||||
public override int ProcessByte(byte input, byte[] output, int outOff)
|
||||
{
|
||||
buf[bufOff++] = input;
|
||||
if (bufOff == buf.Length)
|
||||
{
|
||||
if (outOff + buf.Length > output.Length)
|
||||
{
|
||||
throw new DataLengthException("output buffer too short");
|
||||
}
|
||||
bufOff = 0;
|
||||
return cipher.ProcessBlock(buf, 0, output, outOff);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override byte[] ProcessByte(byte input)
|
||||
{
|
||||
int updateOutputSize = GetUpdateOutputSize(1);
|
||||
byte[] array = ((updateOutputSize > 0) ? new byte[updateOutputSize] : null);
|
||||
int num = ProcessByte(input, array, 0);
|
||||
if (updateOutputSize > 0 && num < updateOutputSize)
|
||||
{
|
||||
byte[] array2 = new byte[num];
|
||||
Array.Copy(array, 0, array2, 0, num);
|
||||
array = array2;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public override byte[] ProcessBytes(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (input == null)
|
||||
{
|
||||
throw new ArgumentNullException("input");
|
||||
}
|
||||
if (length < 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int updateOutputSize = GetUpdateOutputSize(length);
|
||||
byte[] array = ((updateOutputSize > 0) ? new byte[updateOutputSize] : null);
|
||||
int num = ProcessBytes(input, inOff, length, array, 0);
|
||||
if (updateOutputSize > 0 && num < updateOutputSize)
|
||||
{
|
||||
byte[] array2 = new byte[num];
|
||||
Array.Copy(array, 0, array2, 0, num);
|
||||
array = array2;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public override int ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff)
|
||||
{
|
||||
if (length < 1)
|
||||
{
|
||||
if (length < 0)
|
||||
{
|
||||
throw new ArgumentException("Can't have a negative input length!");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int blockSize = GetBlockSize();
|
||||
int updateOutputSize = GetUpdateOutputSize(length);
|
||||
if (updateOutputSize > 0)
|
||||
{
|
||||
Check.OutputLength(output, outOff, updateOutputSize, "output buffer too short");
|
||||
}
|
||||
int num = 0;
|
||||
int num2 = buf.Length - bufOff;
|
||||
if (length > num2)
|
||||
{
|
||||
Array.Copy(input, inOff, buf, bufOff, num2);
|
||||
num += cipher.ProcessBlock(buf, 0, output, outOff);
|
||||
bufOff = 0;
|
||||
length -= num2;
|
||||
inOff += num2;
|
||||
while (length > buf.Length)
|
||||
{
|
||||
num += cipher.ProcessBlock(input, inOff, output, outOff + num);
|
||||
length -= blockSize;
|
||||
inOff += blockSize;
|
||||
}
|
||||
}
|
||||
Array.Copy(input, inOff, buf, bufOff, length);
|
||||
bufOff += length;
|
||||
if (bufOff == buf.Length)
|
||||
{
|
||||
num += cipher.ProcessBlock(buf, 0, output, outOff + num);
|
||||
bufOff = 0;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public override byte[] DoFinal()
|
||||
{
|
||||
byte[] array = BufferedCipherBase.EmptyBuffer;
|
||||
int outputSize = GetOutputSize(0);
|
||||
if (outputSize > 0)
|
||||
{
|
||||
array = new byte[outputSize];
|
||||
int num = DoFinal(array, 0);
|
||||
if (num < array.Length)
|
||||
{
|
||||
byte[] array2 = new byte[num];
|
||||
Array.Copy(array, 0, array2, 0, num);
|
||||
array = array2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public override byte[] DoFinal(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (input == null)
|
||||
{
|
||||
throw new ArgumentNullException("input");
|
||||
}
|
||||
int outputSize = GetOutputSize(inLen);
|
||||
byte[] array = BufferedCipherBase.EmptyBuffer;
|
||||
if (outputSize > 0)
|
||||
{
|
||||
array = new byte[outputSize];
|
||||
int num = ((inLen > 0) ? ProcessBytes(input, inOff, inLen, array, 0) : 0);
|
||||
num += DoFinal(array, num);
|
||||
if (num < array.Length)
|
||||
{
|
||||
byte[] array2 = new byte[num];
|
||||
Array.Copy(array, 0, array2, 0, num);
|
||||
array = array2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (bufOff != 0)
|
||||
{
|
||||
Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned");
|
||||
Check.OutputLength(output, outOff, bufOff, "output buffer too short for DoFinal()");
|
||||
cipher.ProcessBlock(buf, 0, buf, 0);
|
||||
Array.Copy(buf, 0, output, outOff, bufOff);
|
||||
}
|
||||
return bufOff;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Array.Clear(buf, 0, buf.Length);
|
||||
bufOff = 0;
|
||||
cipher.Reset();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
public abstract class BufferedCipherBase : IBufferedCipher
|
||||
{
|
||||
protected static readonly byte[] EmptyBuffer = new byte[0];
|
||||
|
||||
public abstract string AlgorithmName { get; }
|
||||
|
||||
public abstract void Init(bool forEncryption, ICipherParameters parameters);
|
||||
|
||||
public abstract int GetBlockSize();
|
||||
|
||||
public abstract int GetOutputSize(int inputLen);
|
||||
|
||||
public abstract int GetUpdateOutputSize(int inputLen);
|
||||
|
||||
public abstract byte[] ProcessByte(byte input);
|
||||
|
||||
public virtual int ProcessByte(byte input, byte[] output, int outOff)
|
||||
{
|
||||
byte[] array = ProcessByte(input);
|
||||
if (array == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (outOff + array.Length > output.Length)
|
||||
{
|
||||
throw new DataLengthException("output buffer too short");
|
||||
}
|
||||
array.CopyTo(output, outOff);
|
||||
return array.Length;
|
||||
}
|
||||
|
||||
public virtual byte[] ProcessBytes(byte[] input)
|
||||
{
|
||||
return ProcessBytes(input, 0, input.Length);
|
||||
}
|
||||
|
||||
public abstract byte[] ProcessBytes(byte[] input, int inOff, int length);
|
||||
|
||||
public virtual int ProcessBytes(byte[] input, byte[] output, int outOff)
|
||||
{
|
||||
return ProcessBytes(input, 0, input.Length, output, outOff);
|
||||
}
|
||||
|
||||
public virtual int ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff)
|
||||
{
|
||||
byte[] array = ProcessBytes(input, inOff, length);
|
||||
if (array == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (outOff + array.Length > output.Length)
|
||||
{
|
||||
throw new DataLengthException("output buffer too short");
|
||||
}
|
||||
array.CopyTo(output, outOff);
|
||||
return array.Length;
|
||||
}
|
||||
|
||||
public abstract byte[] DoFinal();
|
||||
|
||||
public virtual byte[] DoFinal(byte[] input)
|
||||
{
|
||||
return DoFinal(input, 0, input.Length);
|
||||
}
|
||||
|
||||
public abstract byte[] DoFinal(byte[] input, int inOff, int length);
|
||||
|
||||
public virtual int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
byte[] array = DoFinal();
|
||||
if (outOff + array.Length > output.Length)
|
||||
{
|
||||
throw new DataLengthException("output buffer too short");
|
||||
}
|
||||
array.CopyTo(output, outOff);
|
||||
return array.Length;
|
||||
}
|
||||
|
||||
public virtual int DoFinal(byte[] input, byte[] output, int outOff)
|
||||
{
|
||||
return DoFinal(input, 0, input.Length, output, outOff);
|
||||
}
|
||||
|
||||
public virtual int DoFinal(byte[] input, int inOff, int length, byte[] output, int outOff)
|
||||
{
|
||||
int num = ProcessBytes(input, inOff, length, output, outOff);
|
||||
return num + DoFinal(output, outOff + num);
|
||||
}
|
||||
|
||||
public abstract void Reset();
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Crypto.Engines;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
public class BufferedIesCipher : BufferedCipherBase
|
||||
{
|
||||
private readonly IesEngine engine;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
private MemoryStream buffer = new MemoryStream();
|
||||
|
||||
public override string AlgorithmName => "IES";
|
||||
|
||||
public BufferedIesCipher(IesEngine engine)
|
||||
{
|
||||
if (engine == null)
|
||||
{
|
||||
throw new ArgumentNullException("engine");
|
||||
}
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
public override void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
this.forEncryption = forEncryption;
|
||||
throw Platform.CreateNotImplementedException("IES");
|
||||
}
|
||||
|
||||
public override int GetBlockSize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override int GetOutputSize(int inputLen)
|
||||
{
|
||||
if (engine == null)
|
||||
{
|
||||
throw new InvalidOperationException("cipher not initialised");
|
||||
}
|
||||
int num = inputLen + (int)buffer.Length;
|
||||
if (!forEncryption)
|
||||
{
|
||||
return num - 20;
|
||||
}
|
||||
return num + 20;
|
||||
}
|
||||
|
||||
public override int GetUpdateOutputSize(int inputLen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override byte[] ProcessByte(byte input)
|
||||
{
|
||||
buffer.WriteByte(input);
|
||||
return null;
|
||||
}
|
||||
|
||||
public override byte[] ProcessBytes(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (input == null)
|
||||
{
|
||||
throw new ArgumentNullException("input");
|
||||
}
|
||||
if (inOff < 0)
|
||||
{
|
||||
throw new ArgumentException("inOff");
|
||||
}
|
||||
if (length < 0)
|
||||
{
|
||||
throw new ArgumentException("length");
|
||||
}
|
||||
if (inOff + length > input.Length)
|
||||
{
|
||||
throw new ArgumentException("invalid offset/length specified for input array");
|
||||
}
|
||||
buffer.Write(input, inOff, length);
|
||||
return null;
|
||||
}
|
||||
|
||||
public override byte[] DoFinal()
|
||||
{
|
||||
byte[] array = buffer.ToArray();
|
||||
Reset();
|
||||
return engine.ProcessBlock(array, 0, array.Length);
|
||||
}
|
||||
|
||||
public override byte[] DoFinal(byte[] input, int inOff, int length)
|
||||
{
|
||||
ProcessBytes(input, inOff, length);
|
||||
return DoFinal();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
buffer.SetLength(0L);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
public class BufferedStreamCipher : BufferedCipherBase
|
||||
{
|
||||
private readonly IStreamCipher cipher;
|
||||
|
||||
public override string AlgorithmName => cipher.AlgorithmName;
|
||||
|
||||
public BufferedStreamCipher(IStreamCipher cipher)
|
||||
{
|
||||
if (cipher == null)
|
||||
{
|
||||
throw new ArgumentNullException("cipher");
|
||||
}
|
||||
this.cipher = cipher;
|
||||
}
|
||||
|
||||
public override void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
parameters = ((ParametersWithRandom)parameters).Parameters;
|
||||
}
|
||||
cipher.Init(forEncryption, parameters);
|
||||
}
|
||||
|
||||
public override int GetBlockSize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override int GetOutputSize(int inputLen)
|
||||
{
|
||||
return inputLen;
|
||||
}
|
||||
|
||||
public override int GetUpdateOutputSize(int inputLen)
|
||||
{
|
||||
return inputLen;
|
||||
}
|
||||
|
||||
public override byte[] ProcessByte(byte input)
|
||||
{
|
||||
return new byte[1] { cipher.ReturnByte(input) };
|
||||
}
|
||||
|
||||
public override int ProcessByte(byte input, byte[] output, int outOff)
|
||||
{
|
||||
if (outOff >= output.Length)
|
||||
{
|
||||
throw new DataLengthException("output buffer too short");
|
||||
}
|
||||
output[outOff] = cipher.ReturnByte(input);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override byte[] ProcessBytes(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (length < 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
byte[] array = new byte[length];
|
||||
cipher.ProcessBytes(input, inOff, length, array, 0);
|
||||
return array;
|
||||
}
|
||||
|
||||
public override int ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff)
|
||||
{
|
||||
if (length < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (length > 0)
|
||||
{
|
||||
cipher.ProcessBytes(input, inOff, length, output, outOff);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
public override byte[] DoFinal()
|
||||
{
|
||||
Reset();
|
||||
return BufferedCipherBase.EmptyBuffer;
|
||||
}
|
||||
|
||||
public override byte[] DoFinal(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (length < 1)
|
||||
{
|
||||
return BufferedCipherBase.EmptyBuffer;
|
||||
}
|
||||
byte[] result = ProcessBytes(input, inOff, length);
|
||||
Reset();
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
cipher.Reset();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
internal class Check
|
||||
{
|
||||
internal static void DataLength(bool condition, string msg)
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
throw new DataLengthException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DataLength(byte[] buf, int off, int len, string msg)
|
||||
{
|
||||
if (off + len > buf.Length)
|
||||
{
|
||||
throw new DataLengthException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void OutputLength(byte[] buf, int off, int len, string msg)
|
||||
{
|
||||
if (off + len > buf.Length)
|
||||
{
|
||||
throw new OutputLengthException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
public class CipherKeyGenerator
|
||||
{
|
||||
protected internal SecureRandom random;
|
||||
|
||||
protected internal int strength;
|
||||
|
||||
private bool uninitialised = true;
|
||||
|
||||
private int defaultStrength;
|
||||
|
||||
public int DefaultStrength => defaultStrength;
|
||||
|
||||
public CipherKeyGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
internal CipherKeyGenerator(int defaultStrength)
|
||||
{
|
||||
if (defaultStrength < 1)
|
||||
{
|
||||
throw new ArgumentException("strength must be a positive value", "defaultStrength");
|
||||
}
|
||||
this.defaultStrength = defaultStrength;
|
||||
}
|
||||
|
||||
public void Init(KeyGenerationParameters parameters)
|
||||
{
|
||||
if (parameters == null)
|
||||
{
|
||||
throw new ArgumentNullException("parameters");
|
||||
}
|
||||
uninitialised = false;
|
||||
engineInit(parameters);
|
||||
}
|
||||
|
||||
protected virtual void engineInit(KeyGenerationParameters parameters)
|
||||
{
|
||||
random = parameters.Random;
|
||||
strength = (parameters.Strength + 7) / 8;
|
||||
}
|
||||
|
||||
public byte[] GenerateKey()
|
||||
{
|
||||
if (uninitialised)
|
||||
{
|
||||
if (defaultStrength < 1)
|
||||
{
|
||||
throw new InvalidOperationException("Generator has not been initialised");
|
||||
}
|
||||
uninitialised = false;
|
||||
engineInit(new KeyGenerationParameters(new SecureRandom(), defaultStrength));
|
||||
}
|
||||
return engineGenerateKey();
|
||||
}
|
||||
|
||||
protected virtual byte[] engineGenerateKey()
|
||||
{
|
||||
return SecureRandom.GetNextBytes(random, strength);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
[Serializable]
|
||||
public class CryptoException : Exception
|
||||
{
|
||||
public CryptoException()
|
||||
{
|
||||
}
|
||||
|
||||
public CryptoException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public CryptoException(string message, Exception exception)
|
||||
: base(message, exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto;
|
||||
|
||||
[Serializable]
|
||||
public class DataLengthException : CryptoException
|
||||
{
|
||||
public DataLengthException()
|
||||
{
|
||||
}
|
||||
|
||||
public DataLengthException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public DataLengthException(string message, Exception exception)
|
||||
: base(message, exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Blake2bDigest : IDigest
|
||||
{
|
||||
private const int ROUNDS = 12;
|
||||
|
||||
private const int BLOCK_LENGTH_BYTES = 128;
|
||||
|
||||
private static readonly ulong[] blake2b_IV = new ulong[8] { 7640891576956012808uL, 13503953896175478587uL, 4354685564936845355uL, 11912009170470909681uL, 5840696475078001361uL, 11170449401992604703uL, 2270897969802886507uL, 6620516959819538809uL };
|
||||
|
||||
private static readonly byte[,] blake2b_sigma = new byte[12, 16]
|
||||
{
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15
|
||||
},
|
||||
{
|
||||
14, 10, 4, 8, 9, 15, 13, 6, 1, 12,
|
||||
0, 2, 11, 7, 5, 3
|
||||
},
|
||||
{
|
||||
11, 8, 12, 0, 5, 2, 15, 13, 10, 14,
|
||||
3, 6, 7, 1, 9, 4
|
||||
},
|
||||
{
|
||||
7, 9, 3, 1, 13, 12, 11, 14, 2, 6,
|
||||
5, 10, 4, 0, 15, 8
|
||||
},
|
||||
{
|
||||
9, 0, 5, 7, 2, 4, 10, 15, 14, 1,
|
||||
11, 12, 6, 8, 3, 13
|
||||
},
|
||||
{
|
||||
2, 12, 6, 10, 0, 11, 8, 3, 4, 13,
|
||||
7, 5, 15, 14, 1, 9
|
||||
},
|
||||
{
|
||||
12, 5, 1, 15, 14, 13, 4, 10, 0, 7,
|
||||
6, 3, 9, 2, 8, 11
|
||||
},
|
||||
{
|
||||
13, 11, 7, 14, 12, 1, 3, 9, 5, 0,
|
||||
15, 4, 8, 6, 2, 10
|
||||
},
|
||||
{
|
||||
6, 15, 14, 9, 11, 3, 0, 8, 12, 2,
|
||||
13, 7, 1, 4, 10, 5
|
||||
},
|
||||
{
|
||||
10, 2, 8, 4, 7, 6, 1, 5, 15, 11,
|
||||
9, 14, 3, 12, 13, 0
|
||||
},
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15
|
||||
},
|
||||
{
|
||||
14, 10, 4, 8, 9, 15, 13, 6, 1, 12,
|
||||
0, 2, 11, 7, 5, 3
|
||||
}
|
||||
};
|
||||
|
||||
private int digestLength = 64;
|
||||
|
||||
private int keyLength = 0;
|
||||
|
||||
private byte[] salt = null;
|
||||
|
||||
private byte[] personalization = null;
|
||||
|
||||
private byte[] key = null;
|
||||
|
||||
private byte[] buffer = null;
|
||||
|
||||
private int bufferPos = 0;
|
||||
|
||||
private ulong[] internalState = new ulong[16];
|
||||
|
||||
private ulong[] chainValue = null;
|
||||
|
||||
private ulong t0 = 0uL;
|
||||
|
||||
private ulong t1 = 0uL;
|
||||
|
||||
private ulong f0 = 0uL;
|
||||
|
||||
public virtual string AlgorithmName => "BLAKE2b";
|
||||
|
||||
public Blake2bDigest()
|
||||
: this(512)
|
||||
{
|
||||
}
|
||||
|
||||
public Blake2bDigest(Blake2bDigest digest)
|
||||
{
|
||||
bufferPos = digest.bufferPos;
|
||||
buffer = Arrays.Clone(digest.buffer);
|
||||
keyLength = digest.keyLength;
|
||||
key = Arrays.Clone(digest.key);
|
||||
digestLength = digest.digestLength;
|
||||
chainValue = Arrays.Clone(digest.chainValue);
|
||||
personalization = Arrays.Clone(digest.personalization);
|
||||
salt = Arrays.Clone(digest.salt);
|
||||
t0 = digest.t0;
|
||||
t1 = digest.t1;
|
||||
f0 = digest.f0;
|
||||
}
|
||||
|
||||
public Blake2bDigest(int digestSize)
|
||||
{
|
||||
if (digestSize < 8 || digestSize > 512 || digestSize % 8 != 0)
|
||||
{
|
||||
throw new ArgumentException("BLAKE2b digest bit length must be a multiple of 8 and not greater than 512");
|
||||
}
|
||||
buffer = new byte[128];
|
||||
keyLength = 0;
|
||||
digestLength = digestSize / 8;
|
||||
Init();
|
||||
}
|
||||
|
||||
public Blake2bDigest(byte[] key)
|
||||
{
|
||||
buffer = new byte[128];
|
||||
if (key != null)
|
||||
{
|
||||
this.key = new byte[key.Length];
|
||||
Array.Copy(key, 0, this.key, 0, key.Length);
|
||||
if (key.Length > 64)
|
||||
{
|
||||
throw new ArgumentException("Keys > 64 are not supported");
|
||||
}
|
||||
keyLength = key.Length;
|
||||
Array.Copy(key, 0, buffer, 0, key.Length);
|
||||
bufferPos = 128;
|
||||
}
|
||||
digestLength = 64;
|
||||
Init();
|
||||
}
|
||||
|
||||
public Blake2bDigest(byte[] key, int digestLength, byte[] salt, byte[] personalization)
|
||||
{
|
||||
if (digestLength < 1 || digestLength > 64)
|
||||
{
|
||||
throw new ArgumentException("Invalid digest length (required: 1 - 64)");
|
||||
}
|
||||
this.digestLength = digestLength;
|
||||
buffer = new byte[128];
|
||||
if (salt != null)
|
||||
{
|
||||
if (salt.Length != 16)
|
||||
{
|
||||
throw new ArgumentException("salt length must be exactly 16 bytes");
|
||||
}
|
||||
this.salt = new byte[16];
|
||||
Array.Copy(salt, 0, this.salt, 0, salt.Length);
|
||||
}
|
||||
if (personalization != null)
|
||||
{
|
||||
if (personalization.Length != 16)
|
||||
{
|
||||
throw new ArgumentException("personalization length must be exactly 16 bytes");
|
||||
}
|
||||
this.personalization = new byte[16];
|
||||
Array.Copy(personalization, 0, this.personalization, 0, personalization.Length);
|
||||
}
|
||||
if (key != null)
|
||||
{
|
||||
if (key.Length > 64)
|
||||
{
|
||||
throw new ArgumentException("Keys > 64 are not supported");
|
||||
}
|
||||
this.key = new byte[key.Length];
|
||||
Array.Copy(key, 0, this.key, 0, key.Length);
|
||||
keyLength = key.Length;
|
||||
Array.Copy(key, 0, buffer, 0, key.Length);
|
||||
bufferPos = 128;
|
||||
}
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (chainValue == null)
|
||||
{
|
||||
chainValue = new ulong[8];
|
||||
chainValue[0] = blake2b_IV[0] ^ (ulong)(digestLength | (keyLength << 8) | 0x1010000);
|
||||
chainValue[1] = blake2b_IV[1];
|
||||
chainValue[2] = blake2b_IV[2];
|
||||
chainValue[3] = blake2b_IV[3];
|
||||
chainValue[4] = blake2b_IV[4];
|
||||
chainValue[5] = blake2b_IV[5];
|
||||
if (salt != null)
|
||||
{
|
||||
ulong[] array;
|
||||
(array = chainValue)[4] = array[4] ^ Pack.LE_To_UInt64(salt, 0);
|
||||
(array = chainValue)[5] = array[5] ^ Pack.LE_To_UInt64(salt, 8);
|
||||
}
|
||||
chainValue[6] = blake2b_IV[6];
|
||||
chainValue[7] = blake2b_IV[7];
|
||||
if (personalization != null)
|
||||
{
|
||||
ulong[] array;
|
||||
(array = chainValue)[6] = array[6] ^ Pack.LE_To_UInt64(personalization, 0);
|
||||
(array = chainValue)[7] = array[7] ^ Pack.LE_To_UInt64(personalization, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeInternalState()
|
||||
{
|
||||
Array.Copy(chainValue, 0, internalState, 0, chainValue.Length);
|
||||
Array.Copy(blake2b_IV, 0, internalState, chainValue.Length, 4);
|
||||
internalState[12] = t0 ^ blake2b_IV[4];
|
||||
internalState[13] = t1 ^ blake2b_IV[5];
|
||||
internalState[14] = f0 ^ blake2b_IV[6];
|
||||
internalState[15] = blake2b_IV[7];
|
||||
}
|
||||
|
||||
public virtual void Update(byte b)
|
||||
{
|
||||
int num = 0;
|
||||
if (128 - bufferPos == 0)
|
||||
{
|
||||
t0 += 128uL;
|
||||
if (t0 == 0)
|
||||
{
|
||||
t1++;
|
||||
}
|
||||
Compress(buffer, 0);
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
buffer[0] = b;
|
||||
bufferPos = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[bufferPos] = b;
|
||||
bufferPos++;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] message, int offset, int len)
|
||||
{
|
||||
if (message == null || len == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int num = 0;
|
||||
if (bufferPos != 0)
|
||||
{
|
||||
num = 128 - bufferPos;
|
||||
if (num >= len)
|
||||
{
|
||||
Array.Copy(message, offset, buffer, bufferPos, len);
|
||||
bufferPos += len;
|
||||
return;
|
||||
}
|
||||
Array.Copy(message, offset, buffer, bufferPos, num);
|
||||
t0 += 128uL;
|
||||
if (t0 == 0)
|
||||
{
|
||||
t1++;
|
||||
}
|
||||
Compress(buffer, 0);
|
||||
bufferPos = 0;
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
}
|
||||
int num2 = offset + len - 128;
|
||||
int i;
|
||||
for (i = offset + num; i < num2; i += 128)
|
||||
{
|
||||
t0 += 128uL;
|
||||
if (t0 == 0)
|
||||
{
|
||||
t1++;
|
||||
}
|
||||
Compress(message, i);
|
||||
}
|
||||
Array.Copy(message, i, buffer, 0, offset + len - i);
|
||||
bufferPos += offset + len - i;
|
||||
}
|
||||
|
||||
public virtual int DoFinal(byte[] output, int outOffset)
|
||||
{
|
||||
f0 = ulong.MaxValue;
|
||||
t0 += (ulong)bufferPos;
|
||||
if (bufferPos > 0 && t0 == 0)
|
||||
{
|
||||
t1++;
|
||||
}
|
||||
Compress(buffer, 0);
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
Array.Clear(internalState, 0, internalState.Length);
|
||||
for (int i = 0; i < chainValue.Length && i * 8 < digestLength; i++)
|
||||
{
|
||||
byte[] sourceArray = Pack.UInt64_To_LE(chainValue[i]);
|
||||
if (i * 8 < digestLength - 8)
|
||||
{
|
||||
Array.Copy(sourceArray, 0, output, outOffset + i * 8, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(sourceArray, 0, output, outOffset + i * 8, digestLength - i * 8);
|
||||
}
|
||||
}
|
||||
Array.Clear(chainValue, 0, chainValue.Length);
|
||||
Reset();
|
||||
return digestLength;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
bufferPos = 0;
|
||||
f0 = 0uL;
|
||||
t0 = 0uL;
|
||||
t1 = 0uL;
|
||||
chainValue = null;
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
if (key != null)
|
||||
{
|
||||
Array.Copy(key, 0, buffer, 0, key.Length);
|
||||
bufferPos = 128;
|
||||
}
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Compress(byte[] message, int messagePos)
|
||||
{
|
||||
InitializeInternalState();
|
||||
ulong[] array = new ulong[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
array[i] = Pack.LE_To_UInt64(message, messagePos + i * 8);
|
||||
}
|
||||
for (int j = 0; j < 12; j++)
|
||||
{
|
||||
G(array[blake2b_sigma[j, 0]], array[blake2b_sigma[j, 1]], 0, 4, 8, 12);
|
||||
G(array[blake2b_sigma[j, 2]], array[blake2b_sigma[j, 3]], 1, 5, 9, 13);
|
||||
G(array[blake2b_sigma[j, 4]], array[blake2b_sigma[j, 5]], 2, 6, 10, 14);
|
||||
G(array[blake2b_sigma[j, 6]], array[blake2b_sigma[j, 7]], 3, 7, 11, 15);
|
||||
G(array[blake2b_sigma[j, 8]], array[blake2b_sigma[j, 9]], 0, 5, 10, 15);
|
||||
G(array[blake2b_sigma[j, 10]], array[blake2b_sigma[j, 11]], 1, 6, 11, 12);
|
||||
G(array[blake2b_sigma[j, 12]], array[blake2b_sigma[j, 13]], 2, 7, 8, 13);
|
||||
G(array[blake2b_sigma[j, 14]], array[blake2b_sigma[j, 15]], 3, 4, 9, 14);
|
||||
}
|
||||
for (int k = 0; k < chainValue.Length; k++)
|
||||
{
|
||||
chainValue[k] = chainValue[k] ^ internalState[k] ^ internalState[k + 8];
|
||||
}
|
||||
}
|
||||
|
||||
private void G(ulong m1, ulong m2, int posA, int posB, int posC, int posD)
|
||||
{
|
||||
internalState[posA] = internalState[posA] + internalState[posB] + m1;
|
||||
internalState[posD] = Rotr64(internalState[posD] ^ internalState[posA], 32);
|
||||
internalState[posC] += internalState[posD];
|
||||
internalState[posB] = Rotr64(internalState[posB] ^ internalState[posC], 24);
|
||||
internalState[posA] = internalState[posA] + internalState[posB] + m2;
|
||||
internalState[posD] = Rotr64(internalState[posD] ^ internalState[posA], 16);
|
||||
internalState[posC] += internalState[posD];
|
||||
internalState[posB] = Rotr64(internalState[posB] ^ internalState[posC], 63);
|
||||
}
|
||||
|
||||
private static ulong Rotr64(ulong x, int rot)
|
||||
{
|
||||
return (x >> rot) | (x << -rot);
|
||||
}
|
||||
|
||||
public virtual int GetDigestSize()
|
||||
{
|
||||
return digestLength;
|
||||
}
|
||||
|
||||
public virtual int GetByteLength()
|
||||
{
|
||||
return 128;
|
||||
}
|
||||
|
||||
public virtual void ClearKey()
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
Array.Clear(key, 0, key.Length);
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearSalt()
|
||||
{
|
||||
if (salt != null)
|
||||
{
|
||||
Array.Clear(salt, 0, salt.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Blake2sDigest : IDigest
|
||||
{
|
||||
private const int ROUNDS = 10;
|
||||
|
||||
private const int BLOCK_LENGTH_BYTES = 64;
|
||||
|
||||
private static readonly uint[] blake2s_IV = new uint[8] { 1779033703u, 3144134277u, 1013904242u, 2773480762u, 1359893119u, 2600822924u, 528734635u, 1541459225u };
|
||||
|
||||
private static readonly byte[,] blake2s_sigma = new byte[10, 16]
|
||||
{
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15
|
||||
},
|
||||
{
|
||||
14, 10, 4, 8, 9, 15, 13, 6, 1, 12,
|
||||
0, 2, 11, 7, 5, 3
|
||||
},
|
||||
{
|
||||
11, 8, 12, 0, 5, 2, 15, 13, 10, 14,
|
||||
3, 6, 7, 1, 9, 4
|
||||
},
|
||||
{
|
||||
7, 9, 3, 1, 13, 12, 11, 14, 2, 6,
|
||||
5, 10, 4, 0, 15, 8
|
||||
},
|
||||
{
|
||||
9, 0, 5, 7, 2, 4, 10, 15, 14, 1,
|
||||
11, 12, 6, 8, 3, 13
|
||||
},
|
||||
{
|
||||
2, 12, 6, 10, 0, 11, 8, 3, 4, 13,
|
||||
7, 5, 15, 14, 1, 9
|
||||
},
|
||||
{
|
||||
12, 5, 1, 15, 14, 13, 4, 10, 0, 7,
|
||||
6, 3, 9, 2, 8, 11
|
||||
},
|
||||
{
|
||||
13, 11, 7, 14, 12, 1, 3, 9, 5, 0,
|
||||
15, 4, 8, 6, 2, 10
|
||||
},
|
||||
{
|
||||
6, 15, 14, 9, 11, 3, 0, 8, 12, 2,
|
||||
13, 7, 1, 4, 10, 5
|
||||
},
|
||||
{
|
||||
10, 2, 8, 4, 7, 6, 1, 5, 15, 11,
|
||||
9, 14, 3, 12, 13, 0
|
||||
}
|
||||
};
|
||||
|
||||
private int digestLength = 32;
|
||||
|
||||
private int keyLength = 0;
|
||||
|
||||
private byte[] salt = null;
|
||||
|
||||
private byte[] personalization = null;
|
||||
|
||||
private byte[] key = null;
|
||||
|
||||
private byte[] buffer = null;
|
||||
|
||||
private int bufferPos = 0;
|
||||
|
||||
private uint[] internalState = new uint[16];
|
||||
|
||||
private uint[] chainValue = null;
|
||||
|
||||
private uint t0 = 0u;
|
||||
|
||||
private uint t1 = 0u;
|
||||
|
||||
private uint f0 = 0u;
|
||||
|
||||
public virtual string AlgorithmName => "BLAKE2s";
|
||||
|
||||
public Blake2sDigest()
|
||||
: this(256)
|
||||
{
|
||||
}
|
||||
|
||||
public Blake2sDigest(Blake2sDigest digest)
|
||||
{
|
||||
bufferPos = digest.bufferPos;
|
||||
buffer = Arrays.Clone(digest.buffer);
|
||||
keyLength = digest.keyLength;
|
||||
key = Arrays.Clone(digest.key);
|
||||
digestLength = digest.digestLength;
|
||||
chainValue = Arrays.Clone(digest.chainValue);
|
||||
personalization = Arrays.Clone(digest.personalization);
|
||||
}
|
||||
|
||||
public Blake2sDigest(int digestBits)
|
||||
{
|
||||
if (digestBits < 8 || digestBits > 256 || digestBits % 8 != 0)
|
||||
{
|
||||
throw new ArgumentException("BLAKE2s digest bit length must be a multiple of 8 and not greater than 256");
|
||||
}
|
||||
buffer = new byte[64];
|
||||
keyLength = 0;
|
||||
digestLength = digestBits / 8;
|
||||
Init();
|
||||
}
|
||||
|
||||
public Blake2sDigest(byte[] key)
|
||||
{
|
||||
buffer = new byte[64];
|
||||
if (key != null)
|
||||
{
|
||||
if (key.Length > 32)
|
||||
{
|
||||
throw new ArgumentException("Keys > 32 are not supported");
|
||||
}
|
||||
this.key = new byte[key.Length];
|
||||
Array.Copy(key, 0, this.key, 0, key.Length);
|
||||
keyLength = key.Length;
|
||||
Array.Copy(key, 0, buffer, 0, key.Length);
|
||||
bufferPos = 64;
|
||||
}
|
||||
digestLength = 32;
|
||||
Init();
|
||||
}
|
||||
|
||||
public Blake2sDigest(byte[] key, int digestBytes, byte[] salt, byte[] personalization)
|
||||
{
|
||||
if (digestBytes < 1 || digestBytes > 32)
|
||||
{
|
||||
throw new ArgumentException("Invalid digest length (required: 1 - 32)");
|
||||
}
|
||||
digestLength = digestBytes;
|
||||
buffer = new byte[64];
|
||||
if (salt != null)
|
||||
{
|
||||
if (salt.Length != 8)
|
||||
{
|
||||
throw new ArgumentException("Salt length must be exactly 8 bytes");
|
||||
}
|
||||
this.salt = new byte[8];
|
||||
Array.Copy(salt, 0, this.salt, 0, salt.Length);
|
||||
}
|
||||
if (personalization != null)
|
||||
{
|
||||
if (personalization.Length != 8)
|
||||
{
|
||||
throw new ArgumentException("Personalization length must be exactly 8 bytes");
|
||||
}
|
||||
this.personalization = new byte[8];
|
||||
Array.Copy(personalization, 0, this.personalization, 0, personalization.Length);
|
||||
}
|
||||
if (key != null)
|
||||
{
|
||||
if (key.Length > 32)
|
||||
{
|
||||
throw new ArgumentException("Keys > 32 bytes are not supported");
|
||||
}
|
||||
this.key = new byte[key.Length];
|
||||
Array.Copy(key, 0, this.key, 0, key.Length);
|
||||
keyLength = key.Length;
|
||||
Array.Copy(key, 0, buffer, 0, key.Length);
|
||||
bufferPos = 64;
|
||||
}
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (chainValue == null)
|
||||
{
|
||||
chainValue = new uint[8];
|
||||
chainValue[0] = blake2s_IV[0] ^ (uint)(digestLength | (keyLength << 8) | 0x1010000);
|
||||
chainValue[1] = blake2s_IV[1];
|
||||
chainValue[2] = blake2s_IV[2];
|
||||
chainValue[3] = blake2s_IV[3];
|
||||
chainValue[4] = blake2s_IV[4];
|
||||
chainValue[5] = blake2s_IV[5];
|
||||
if (salt != null)
|
||||
{
|
||||
uint[] array;
|
||||
(array = chainValue)[4] = array[4] ^ Pack.LE_To_UInt32(salt, 0);
|
||||
(array = chainValue)[5] = array[5] ^ Pack.LE_To_UInt32(salt, 4);
|
||||
}
|
||||
chainValue[6] = blake2s_IV[6];
|
||||
chainValue[7] = blake2s_IV[7];
|
||||
if (personalization != null)
|
||||
{
|
||||
uint[] array;
|
||||
(array = chainValue)[6] = array[6] ^ Pack.LE_To_UInt32(personalization, 0);
|
||||
(array = chainValue)[7] = array[7] ^ Pack.LE_To_UInt32(personalization, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeInternalState()
|
||||
{
|
||||
Array.Copy(chainValue, 0, internalState, 0, chainValue.Length);
|
||||
Array.Copy(blake2s_IV, 0, internalState, chainValue.Length, 4);
|
||||
internalState[12] = t0 ^ blake2s_IV[4];
|
||||
internalState[13] = t1 ^ blake2s_IV[5];
|
||||
internalState[14] = f0 ^ blake2s_IV[6];
|
||||
internalState[15] = blake2s_IV[7];
|
||||
}
|
||||
|
||||
public virtual void Update(byte b)
|
||||
{
|
||||
if (64 - bufferPos == 0)
|
||||
{
|
||||
t0 += 64u;
|
||||
if (t0 == 0)
|
||||
{
|
||||
t1++;
|
||||
}
|
||||
Compress(buffer, 0);
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
buffer[0] = b;
|
||||
bufferPos = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[bufferPos] = b;
|
||||
bufferPos++;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] message, int offset, int len)
|
||||
{
|
||||
if (message == null || len == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int num = 0;
|
||||
if (bufferPos != 0)
|
||||
{
|
||||
num = 64 - bufferPos;
|
||||
if (num >= len)
|
||||
{
|
||||
Array.Copy(message, offset, buffer, bufferPos, len);
|
||||
bufferPos += len;
|
||||
return;
|
||||
}
|
||||
Array.Copy(message, offset, buffer, bufferPos, num);
|
||||
t0 += 64u;
|
||||
if (t0 == 0)
|
||||
{
|
||||
t1++;
|
||||
}
|
||||
Compress(buffer, 0);
|
||||
bufferPos = 0;
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
}
|
||||
int num2 = offset + len - 64;
|
||||
int i;
|
||||
for (i = offset + num; i < num2; i += 64)
|
||||
{
|
||||
t0 += 64u;
|
||||
if (t0 == 0)
|
||||
{
|
||||
t1++;
|
||||
}
|
||||
Compress(message, i);
|
||||
}
|
||||
Array.Copy(message, i, buffer, 0, offset + len - i);
|
||||
bufferPos += offset + len - i;
|
||||
}
|
||||
|
||||
public virtual int DoFinal(byte[] output, int outOffset)
|
||||
{
|
||||
f0 = uint.MaxValue;
|
||||
t0 += (uint)bufferPos;
|
||||
if (t0 < 0 && bufferPos > 0L - (long)t0)
|
||||
{
|
||||
t1++;
|
||||
}
|
||||
Compress(buffer, 0);
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
Array.Clear(internalState, 0, internalState.Length);
|
||||
for (int i = 0; i < chainValue.Length && i * 4 < digestLength; i++)
|
||||
{
|
||||
byte[] sourceArray = Pack.UInt32_To_LE(chainValue[i]);
|
||||
if (i * 4 < digestLength - 4)
|
||||
{
|
||||
Array.Copy(sourceArray, 0, output, outOffset + i * 4, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(sourceArray, 0, output, outOffset + i * 4, digestLength - i * 4);
|
||||
}
|
||||
}
|
||||
Array.Clear(chainValue, 0, chainValue.Length);
|
||||
Reset();
|
||||
return digestLength;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
bufferPos = 0;
|
||||
f0 = 0u;
|
||||
t0 = 0u;
|
||||
t1 = 0u;
|
||||
chainValue = null;
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
if (key != null)
|
||||
{
|
||||
Array.Copy(key, 0, buffer, 0, key.Length);
|
||||
bufferPos = 64;
|
||||
}
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Compress(byte[] message, int messagePos)
|
||||
{
|
||||
InitializeInternalState();
|
||||
uint[] array = new uint[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
array[i] = Pack.LE_To_UInt32(message, messagePos + i * 4);
|
||||
}
|
||||
for (int j = 0; j < 10; j++)
|
||||
{
|
||||
G(array[blake2s_sigma[j, 0]], array[blake2s_sigma[j, 1]], 0, 4, 8, 12);
|
||||
G(array[blake2s_sigma[j, 2]], array[blake2s_sigma[j, 3]], 1, 5, 9, 13);
|
||||
G(array[blake2s_sigma[j, 4]], array[blake2s_sigma[j, 5]], 2, 6, 10, 14);
|
||||
G(array[blake2s_sigma[j, 6]], array[blake2s_sigma[j, 7]], 3, 7, 11, 15);
|
||||
G(array[blake2s_sigma[j, 8]], array[blake2s_sigma[j, 9]], 0, 5, 10, 15);
|
||||
G(array[blake2s_sigma[j, 10]], array[blake2s_sigma[j, 11]], 1, 6, 11, 12);
|
||||
G(array[blake2s_sigma[j, 12]], array[blake2s_sigma[j, 13]], 2, 7, 8, 13);
|
||||
G(array[blake2s_sigma[j, 14]], array[blake2s_sigma[j, 15]], 3, 4, 9, 14);
|
||||
}
|
||||
for (int k = 0; k < chainValue.Length; k++)
|
||||
{
|
||||
chainValue[k] = chainValue[k] ^ internalState[k] ^ internalState[k + 8];
|
||||
}
|
||||
}
|
||||
|
||||
private void G(uint m1, uint m2, int posA, int posB, int posC, int posD)
|
||||
{
|
||||
internalState[posA] = internalState[posA] + internalState[posB] + m1;
|
||||
internalState[posD] = rotr32(internalState[posD] ^ internalState[posA], 16);
|
||||
internalState[posC] += internalState[posD];
|
||||
internalState[posB] = rotr32(internalState[posB] ^ internalState[posC], 12);
|
||||
internalState[posA] = internalState[posA] + internalState[posB] + m2;
|
||||
internalState[posD] = rotr32(internalState[posD] ^ internalState[posA], 8);
|
||||
internalState[posC] += internalState[posD];
|
||||
internalState[posB] = rotr32(internalState[posB] ^ internalState[posC], 7);
|
||||
}
|
||||
|
||||
private uint rotr32(uint x, int rot)
|
||||
{
|
||||
return (x >> rot) | (x << -rot);
|
||||
}
|
||||
|
||||
public virtual int GetDigestSize()
|
||||
{
|
||||
return digestLength;
|
||||
}
|
||||
|
||||
public virtual int GetByteLength()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public virtual void ClearKey()
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
Array.Clear(key, 0, key.Length);
|
||||
Array.Clear(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearSalt()
|
||||
{
|
||||
if (salt != null)
|
||||
{
|
||||
Array.Clear(salt, 0, salt.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,624 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Dstu7564Digest : IDigest, IMemoable
|
||||
{
|
||||
private const int NB_512 = 8;
|
||||
|
||||
private const int NB_1024 = 16;
|
||||
|
||||
private const int NR_512 = 10;
|
||||
|
||||
private const int NR_1024 = 14;
|
||||
|
||||
private int hashSize;
|
||||
|
||||
private int blockSize;
|
||||
|
||||
private int columns;
|
||||
|
||||
private int rounds;
|
||||
|
||||
private ulong[] state;
|
||||
|
||||
private ulong[] tempState1;
|
||||
|
||||
private ulong[] tempState2;
|
||||
|
||||
private ulong inputBlocks;
|
||||
|
||||
private int bufOff;
|
||||
|
||||
private byte[] buf;
|
||||
|
||||
private static readonly byte[] S0 = new byte[256]
|
||||
{
|
||||
168, 67, 95, 6, 107, 117, 108, 89, 113, 223,
|
||||
135, 149, 23, 240, 216, 9, 109, 243, 29, 203,
|
||||
201, 77, 44, 175, 121, 224, 151, 253, 111, 75,
|
||||
69, 57, 62, 221, 163, 79, 180, 182, 154, 14,
|
||||
31, 191, 21, 225, 73, 210, 147, 198, 146, 114,
|
||||
158, 97, 209, 99, 250, 238, 244, 25, 213, 173,
|
||||
88, 164, 187, 161, 220, 242, 131, 55, 66, 228,
|
||||
122, 50, 156, 204, 171, 74, 143, 110, 4, 39,
|
||||
46, 231, 226, 90, 150, 22, 35, 43, 194, 101,
|
||||
102, 15, 188, 169, 71, 65, 52, 72, 252, 183,
|
||||
106, 136, 165, 83, 134, 249, 91, 219, 56, 123,
|
||||
195, 30, 34, 51, 36, 40, 54, 199, 178, 59,
|
||||
142, 119, 186, 245, 20, 159, 8, 85, 155, 76,
|
||||
254, 96, 92, 218, 24, 70, 205, 125, 33, 176,
|
||||
63, 27, 137, 255, 235, 132, 105, 58, 157, 215,
|
||||
211, 112, 103, 64, 181, 222, 93, 48, 145, 177,
|
||||
120, 17, 1, 229, 0, 104, 152, 160, 197, 2,
|
||||
166, 116, 45, 11, 162, 118, 179, 190, 206, 189,
|
||||
174, 233, 138, 49, 28, 236, 241, 153, 148, 170,
|
||||
246, 38, 47, 239, 232, 140, 53, 3, 212, 127,
|
||||
251, 5, 193, 94, 144, 32, 61, 130, 247, 234,
|
||||
10, 13, 126, 248, 80, 26, 196, 7, 87, 184,
|
||||
60, 98, 227, 200, 172, 82, 100, 16, 208, 217,
|
||||
19, 12, 18, 41, 81, 185, 207, 214, 115, 141,
|
||||
129, 84, 192, 237, 78, 68, 167, 42, 133, 37,
|
||||
230, 202, 124, 139, 86, 128
|
||||
};
|
||||
|
||||
private static readonly byte[] S1 = new byte[256]
|
||||
{
|
||||
206, 187, 235, 146, 234, 203, 19, 193, 233, 58,
|
||||
214, 178, 210, 144, 23, 248, 66, 21, 86, 180,
|
||||
101, 28, 136, 67, 197, 92, 54, 186, 245, 87,
|
||||
103, 141, 49, 246, 100, 88, 158, 244, 34, 170,
|
||||
117, 15, 2, 177, 223, 109, 115, 77, 124, 38,
|
||||
46, 247, 8, 93, 68, 62, 159, 20, 200, 174,
|
||||
84, 16, 216, 188, 26, 107, 105, 243, 189, 51,
|
||||
171, 250, 209, 155, 104, 78, 22, 149, 145, 238,
|
||||
76, 99, 142, 91, 204, 60, 25, 161, 129, 73,
|
||||
123, 217, 111, 55, 96, 202, 231, 43, 72, 253,
|
||||
150, 69, 252, 65, 18, 13, 121, 229, 137, 140,
|
||||
227, 32, 48, 220, 183, 108, 74, 181, 63, 151,
|
||||
212, 98, 45, 6, 164, 165, 131, 95, 42, 218,
|
||||
201, 0, 126, 162, 85, 191, 17, 213, 156, 207,
|
||||
14, 10, 61, 81, 125, 147, 27, 254, 196, 71,
|
||||
9, 134, 11, 143, 157, 106, 7, 185, 176, 152,
|
||||
24, 50, 113, 75, 239, 59, 112, 160, 228, 64,
|
||||
255, 195, 169, 230, 120, 249, 139, 70, 128, 30,
|
||||
56, 225, 184, 168, 224, 12, 35, 118, 29, 37,
|
||||
36, 5, 241, 110, 148, 40, 154, 132, 232, 163,
|
||||
79, 119, 211, 133, 226, 82, 242, 130, 80, 122,
|
||||
47, 116, 83, 179, 97, 175, 57, 53, 222, 205,
|
||||
31, 153, 172, 173, 114, 44, 221, 208, 135, 190,
|
||||
94, 166, 236, 4, 198, 3, 52, 251, 219, 89,
|
||||
182, 194, 1, 240, 90, 237, 167, 102, 33, 127,
|
||||
138, 39, 199, 192, 41, 215
|
||||
};
|
||||
|
||||
private static readonly byte[] S2 = new byte[256]
|
||||
{
|
||||
147, 217, 154, 181, 152, 34, 69, 252, 186, 106,
|
||||
223, 2, 159, 220, 81, 89, 74, 23, 43, 194,
|
||||
148, 244, 187, 163, 98, 228, 113, 212, 205, 112,
|
||||
22, 225, 73, 60, 192, 216, 92, 155, 173, 133,
|
||||
83, 161, 122, 200, 45, 224, 209, 114, 166, 44,
|
||||
196, 227, 118, 120, 183, 180, 9, 59, 14, 65,
|
||||
76, 222, 178, 144, 37, 165, 215, 3, 17, 0,
|
||||
195, 46, 146, 239, 78, 18, 157, 125, 203, 53,
|
||||
16, 213, 79, 158, 77, 169, 85, 198, 208, 123,
|
||||
24, 151, 211, 54, 230, 72, 86, 129, 143, 119,
|
||||
204, 156, 185, 226, 172, 184, 47, 21, 164, 124,
|
||||
218, 56, 30, 11, 5, 214, 20, 110, 108, 126,
|
||||
102, 253, 177, 229, 96, 175, 94, 51, 135, 201,
|
||||
240, 93, 109, 63, 136, 141, 199, 247, 29, 233,
|
||||
236, 237, 128, 41, 39, 207, 153, 168, 80, 15,
|
||||
55, 36, 40, 48, 149, 210, 62, 91, 64, 131,
|
||||
179, 105, 87, 31, 7, 28, 138, 188, 32, 235,
|
||||
206, 142, 171, 238, 49, 162, 115, 249, 202, 58,
|
||||
26, 251, 13, 193, 254, 250, 242, 111, 189, 150,
|
||||
221, 67, 82, 182, 8, 243, 174, 190, 25, 137,
|
||||
50, 38, 176, 234, 75, 100, 132, 130, 107, 245,
|
||||
121, 191, 1, 95, 117, 99, 27, 35, 61, 104,
|
||||
42, 101, 232, 145, 246, 255, 19, 88, 241, 71,
|
||||
10, 127, 197, 167, 231, 97, 90, 6, 70, 68,
|
||||
66, 4, 160, 219, 57, 134, 84, 170, 140, 52,
|
||||
33, 139, 248, 12, 116, 103
|
||||
};
|
||||
|
||||
private static readonly byte[] S3 = new byte[256]
|
||||
{
|
||||
104, 141, 202, 77, 115, 75, 78, 42, 212, 82,
|
||||
38, 179, 84, 30, 25, 31, 34, 3, 70, 61,
|
||||
45, 74, 83, 131, 19, 138, 183, 213, 37, 121,
|
||||
245, 189, 88, 47, 13, 2, 237, 81, 158, 17,
|
||||
242, 62, 85, 94, 209, 22, 60, 102, 112, 93,
|
||||
243, 69, 64, 204, 232, 148, 86, 8, 206, 26,
|
||||
58, 210, 225, 223, 181, 56, 110, 14, 229, 244,
|
||||
249, 134, 233, 79, 214, 133, 35, 207, 50, 153,
|
||||
49, 20, 174, 238, 200, 72, 211, 48, 161, 146,
|
||||
65, 177, 24, 196, 44, 113, 114, 68, 21, 253,
|
||||
55, 190, 95, 170, 155, 136, 216, 171, 137, 156,
|
||||
250, 96, 234, 188, 98, 12, 36, 166, 168, 236,
|
||||
103, 32, 219, 124, 40, 221, 172, 91, 52, 126,
|
||||
16, 241, 123, 143, 99, 160, 5, 154, 67, 119,
|
||||
33, 191, 39, 9, 195, 159, 182, 215, 41, 194,
|
||||
235, 192, 164, 139, 140, 29, 251, 255, 193, 178,
|
||||
151, 46, 248, 101, 246, 117, 7, 4, 73, 51,
|
||||
228, 217, 185, 208, 66, 199, 108, 144, 0, 142,
|
||||
111, 80, 1, 197, 218, 71, 63, 205, 105, 162,
|
||||
226, 122, 167, 198, 147, 15, 10, 6, 230, 43,
|
||||
150, 163, 28, 175, 106, 18, 132, 57, 231, 176,
|
||||
130, 247, 254, 157, 135, 92, 129, 53, 222, 180,
|
||||
165, 252, 128, 239, 203, 187, 107, 118, 186, 90,
|
||||
125, 120, 11, 149, 227, 173, 116, 152, 59, 54,
|
||||
100, 109, 220, 240, 89, 169, 76, 23, 127, 145,
|
||||
184, 201, 87, 27, 224, 97
|
||||
};
|
||||
|
||||
public virtual string AlgorithmName => "DSTU7564";
|
||||
|
||||
public Dstu7564Digest(Dstu7564Digest digest)
|
||||
{
|
||||
CopyIn(digest);
|
||||
}
|
||||
|
||||
private void CopyIn(Dstu7564Digest digest)
|
||||
{
|
||||
hashSize = digest.hashSize;
|
||||
blockSize = digest.blockSize;
|
||||
rounds = digest.rounds;
|
||||
if (columns > 0 && columns == digest.columns)
|
||||
{
|
||||
Array.Copy(digest.state, 0, state, 0, columns);
|
||||
Array.Copy(digest.buf, 0, buf, 0, blockSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
columns = digest.columns;
|
||||
state = Arrays.Clone(digest.state);
|
||||
tempState1 = new ulong[columns];
|
||||
tempState2 = new ulong[columns];
|
||||
buf = Arrays.Clone(digest.buf);
|
||||
}
|
||||
inputBlocks = digest.inputBlocks;
|
||||
bufOff = digest.bufOff;
|
||||
}
|
||||
|
||||
public Dstu7564Digest(int hashSizeBits)
|
||||
{
|
||||
if (hashSizeBits == 256 || hashSizeBits == 384 || hashSizeBits == 512)
|
||||
{
|
||||
hashSize = hashSizeBits / 8;
|
||||
if (hashSizeBits > 256)
|
||||
{
|
||||
columns = 16;
|
||||
rounds = 14;
|
||||
}
|
||||
else
|
||||
{
|
||||
columns = 8;
|
||||
rounds = 10;
|
||||
}
|
||||
blockSize = columns << 3;
|
||||
state = new ulong[columns];
|
||||
state[0] = (ulong)blockSize;
|
||||
tempState1 = new ulong[columns];
|
||||
tempState2 = new ulong[columns];
|
||||
buf = new byte[blockSize];
|
||||
return;
|
||||
}
|
||||
throw new ArgumentException("Hash size is not recommended. Use 256/384/512 instead");
|
||||
}
|
||||
|
||||
public virtual int GetDigestSize()
|
||||
{
|
||||
return hashSize;
|
||||
}
|
||||
|
||||
public virtual int GetByteLength()
|
||||
{
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
public virtual void Update(byte input)
|
||||
{
|
||||
buf[bufOff++] = input;
|
||||
if (bufOff == blockSize)
|
||||
{
|
||||
ProcessBlock(buf, 0);
|
||||
bufOff = 0;
|
||||
inputBlocks++;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] input, int inOff, int length)
|
||||
{
|
||||
while (bufOff != 0 && length > 0)
|
||||
{
|
||||
Update(input[inOff++]);
|
||||
length--;
|
||||
}
|
||||
if (length > 0)
|
||||
{
|
||||
while (length >= blockSize)
|
||||
{
|
||||
ProcessBlock(input, inOff);
|
||||
inOff += blockSize;
|
||||
length -= blockSize;
|
||||
inputBlocks++;
|
||||
}
|
||||
while (length > 0)
|
||||
{
|
||||
Update(input[inOff++]);
|
||||
length--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
int num = bufOff;
|
||||
buf[bufOff++] = 128;
|
||||
int num2 = blockSize - 12;
|
||||
if (bufOff > num2)
|
||||
{
|
||||
while (bufOff < blockSize)
|
||||
{
|
||||
buf[bufOff++] = 0;
|
||||
}
|
||||
bufOff = 0;
|
||||
ProcessBlock(buf, 0);
|
||||
}
|
||||
while (bufOff < num2)
|
||||
{
|
||||
buf[bufOff++] = 0;
|
||||
}
|
||||
ulong num3 = (ulong)((long)(inputBlocks & 0xFFFFFFFFu) * (long)blockSize + (uint)num << 3);
|
||||
Pack.UInt32_To_LE((uint)num3, buf, bufOff);
|
||||
bufOff += 4;
|
||||
num3 >>= 32;
|
||||
num3 += (ulong)((long)(inputBlocks >> 32) * (long)blockSize << 3);
|
||||
Pack.UInt64_To_LE(num3, buf, bufOff);
|
||||
ProcessBlock(buf, 0);
|
||||
Array.Copy(state, 0, tempState1, 0, columns);
|
||||
P(tempState1);
|
||||
for (int i = 0; i < columns; i++)
|
||||
{
|
||||
ulong[] array2;
|
||||
ulong[] array = (array2 = state);
|
||||
int num4 = i;
|
||||
nint num5 = num4;
|
||||
array[num4] = array2[num5] ^ tempState1[i];
|
||||
}
|
||||
int num6 = hashSize / 8;
|
||||
for (int j = columns - num6; j < columns; j++)
|
||||
{
|
||||
Pack.UInt64_To_LE(state[j], output, outOff);
|
||||
outOff += 8;
|
||||
}
|
||||
Reset();
|
||||
return hashSize;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
Array.Clear(state, 0, state.Length);
|
||||
state[0] = (ulong)blockSize;
|
||||
inputBlocks = 0uL;
|
||||
bufOff = 0;
|
||||
}
|
||||
|
||||
protected virtual void ProcessBlock(byte[] input, int inOff)
|
||||
{
|
||||
int num = inOff;
|
||||
for (int i = 0; i < columns; i++)
|
||||
{
|
||||
ulong num2 = Pack.LE_To_UInt64(input, num);
|
||||
num += 8;
|
||||
tempState1[i] = state[i] ^ num2;
|
||||
tempState2[i] = num2;
|
||||
}
|
||||
P(tempState1);
|
||||
Q(tempState2);
|
||||
for (int j = 0; j < columns; j++)
|
||||
{
|
||||
ulong[] array2;
|
||||
ulong[] array = (array2 = state);
|
||||
int num3 = j;
|
||||
nint num4 = num3;
|
||||
array[num3] = array2[num4] ^ (tempState1[j] ^ tempState2[j]);
|
||||
}
|
||||
}
|
||||
|
||||
private void P(ulong[] s)
|
||||
{
|
||||
for (int i = 0; i < rounds; i++)
|
||||
{
|
||||
ulong num = (ulong)i;
|
||||
for (int j = 0; j < columns; j++)
|
||||
{
|
||||
ulong[] array2;
|
||||
ulong[] array = (array2 = s);
|
||||
int num2 = j;
|
||||
nint num3 = num2;
|
||||
array[num2] = array2[num3] ^ num;
|
||||
num += 16;
|
||||
}
|
||||
ShiftRows(s);
|
||||
SubBytes(s);
|
||||
MixColumns(s);
|
||||
}
|
||||
}
|
||||
|
||||
private void Q(ulong[] s)
|
||||
{
|
||||
for (int i = 0; i < rounds; i++)
|
||||
{
|
||||
ulong num = (ulong)(((long)((columns - 1 << 4) ^ i) << 56) | 0xF0F0F0F0F0F0F3L);
|
||||
for (int j = 0; j < columns; j++)
|
||||
{
|
||||
ulong[] array2;
|
||||
ulong[] array = (array2 = s);
|
||||
int num2 = j;
|
||||
nint num3 = num2;
|
||||
array[num2] = array2[num3] + num;
|
||||
num -= 1152921504606846976L;
|
||||
}
|
||||
ShiftRows(s);
|
||||
SubBytes(s);
|
||||
MixColumns(s);
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong MixColumn(ulong c)
|
||||
{
|
||||
ulong num = ((c & 0x7F7F7F7F7F7F7F7FL) << 1) ^ (((c & 0x8080808080808080uL) >> 7) * 29);
|
||||
ulong num2 = Rotate(8, c) ^ c;
|
||||
num2 ^= Rotate(16, num2);
|
||||
num2 ^= Rotate(48, c);
|
||||
ulong num3 = num2 ^ c ^ num;
|
||||
num3 = ((num3 & 0x3F3F3F3F3F3F3F3FL) << 2) ^ (((num3 & 0x8080808080808080uL) >> 6) * 29) ^ (((num3 & 0x4040404040404040L) >> 6) * 29);
|
||||
return num2 ^ Rotate(32, num3) ^ Rotate(40, num) ^ Rotate(48, num);
|
||||
}
|
||||
|
||||
private void MixColumns(ulong[] s)
|
||||
{
|
||||
for (int i = 0; i < columns; i++)
|
||||
{
|
||||
s[i] = MixColumn(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong Rotate(int n, ulong x)
|
||||
{
|
||||
return (x >> n) | (x << -n);
|
||||
}
|
||||
|
||||
private void ShiftRows(ulong[] s)
|
||||
{
|
||||
switch (columns)
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
ulong num18 = s[0];
|
||||
ulong num19 = s[1];
|
||||
ulong num20 = s[2];
|
||||
ulong num21 = s[3];
|
||||
ulong num22 = s[4];
|
||||
ulong num23 = s[5];
|
||||
ulong num24 = s[6];
|
||||
ulong num25 = s[7];
|
||||
ulong num26 = (num18 ^ num22) & 0xFFFFFFFF00000000uL;
|
||||
num18 ^= num26;
|
||||
num22 ^= num26;
|
||||
num26 = (num19 ^ num23) & 0xFFFFFFFF000000L;
|
||||
num19 ^= num26;
|
||||
num23 ^= num26;
|
||||
num26 = (num20 ^ num24) & 0xFFFFFFFF0000L;
|
||||
num20 ^= num26;
|
||||
num24 ^= num26;
|
||||
num26 = (num21 ^ num25) & 0xFFFFFFFF00L;
|
||||
num21 ^= num26;
|
||||
num25 ^= num26;
|
||||
num26 = (num18 ^ num20) & 0xFFFF0000FFFF0000uL;
|
||||
num18 ^= num26;
|
||||
num20 ^= num26;
|
||||
num26 = (num19 ^ num21) & 0xFFFF0000FFFF00L;
|
||||
num19 ^= num26;
|
||||
num21 ^= num26;
|
||||
num26 = (num22 ^ num24) & 0xFFFF0000FFFF0000uL;
|
||||
num22 ^= num26;
|
||||
num24 ^= num26;
|
||||
num26 = (num23 ^ num25) & 0xFFFF0000FFFF00L;
|
||||
num23 ^= num26;
|
||||
num25 ^= num26;
|
||||
num26 = (num18 ^ num19) & 0xFF00FF00FF00FF00uL;
|
||||
num18 ^= num26;
|
||||
num19 ^= num26;
|
||||
num26 = (num20 ^ num21) & 0xFF00FF00FF00FF00uL;
|
||||
num20 ^= num26;
|
||||
num21 ^= num26;
|
||||
num26 = (num22 ^ num23) & 0xFF00FF00FF00FF00uL;
|
||||
num22 ^= num26;
|
||||
num23 ^= num26;
|
||||
num26 = (num24 ^ num25) & 0xFF00FF00FF00FF00uL;
|
||||
num24 ^= num26;
|
||||
num25 ^= num26;
|
||||
s[0] = num18;
|
||||
s[1] = num19;
|
||||
s[2] = num20;
|
||||
s[3] = num21;
|
||||
s[4] = num22;
|
||||
s[5] = num23;
|
||||
s[6] = num24;
|
||||
s[7] = num25;
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
ulong num = s[0];
|
||||
ulong num2 = s[1];
|
||||
ulong num3 = s[2];
|
||||
ulong num4 = s[3];
|
||||
ulong num5 = s[4];
|
||||
ulong num6 = s[5];
|
||||
ulong num7 = s[6];
|
||||
ulong num8 = s[7];
|
||||
ulong num9 = s[8];
|
||||
ulong num10 = s[9];
|
||||
ulong num11 = s[10];
|
||||
ulong num12 = s[11];
|
||||
ulong num13 = s[12];
|
||||
ulong num14 = s[13];
|
||||
ulong num15 = s[14];
|
||||
ulong num16 = s[15];
|
||||
ulong num17 = (num ^ num9) & 0xFF00000000000000uL;
|
||||
num ^= num17;
|
||||
num9 ^= num17;
|
||||
num17 = (num2 ^ num10) & 0xFF00000000000000uL;
|
||||
num2 ^= num17;
|
||||
num10 ^= num17;
|
||||
num17 = (num3 ^ num11) & 0xFFFF000000000000uL;
|
||||
num3 ^= num17;
|
||||
num11 ^= num17;
|
||||
num17 = (num4 ^ num12) & 0xFFFFFF0000000000uL;
|
||||
num4 ^= num17;
|
||||
num12 ^= num17;
|
||||
num17 = (num5 ^ num13) & 0xFFFFFFFF00000000uL;
|
||||
num5 ^= num17;
|
||||
num13 ^= num17;
|
||||
num17 = (num6 ^ num14) & 0xFFFFFFFF000000L;
|
||||
num6 ^= num17;
|
||||
num14 ^= num17;
|
||||
num17 = (num7 ^ num15) & 0xFFFFFFFFFF0000L;
|
||||
num7 ^= num17;
|
||||
num15 ^= num17;
|
||||
num17 = (num8 ^ num16) & 0xFFFFFFFFFFFF00L;
|
||||
num8 ^= num17;
|
||||
num16 ^= num17;
|
||||
num17 = (num ^ num5) & 0xFFFFFF00000000L;
|
||||
num ^= num17;
|
||||
num5 ^= num17;
|
||||
num17 = (num2 ^ num6) & 0xFFFFFFFFFF000000uL;
|
||||
num2 ^= num17;
|
||||
num6 ^= num17;
|
||||
num17 = (num3 ^ num7) & 0xFF00FFFFFFFF0000uL;
|
||||
num3 ^= num17;
|
||||
num7 ^= num17;
|
||||
num17 = (num4 ^ num8) & 0xFF0000FFFFFFFF00uL;
|
||||
num4 ^= num17;
|
||||
num8 ^= num17;
|
||||
num17 = (num9 ^ num13) & 0xFFFFFF00000000L;
|
||||
num9 ^= num17;
|
||||
num13 ^= num17;
|
||||
num17 = (num10 ^ num14) & 0xFFFFFFFFFF000000uL;
|
||||
num10 ^= num17;
|
||||
num14 ^= num17;
|
||||
num17 = (num11 ^ num15) & 0xFF00FFFFFFFF0000uL;
|
||||
num11 ^= num17;
|
||||
num15 ^= num17;
|
||||
num17 = (num12 ^ num16) & 0xFF0000FFFFFFFF00uL;
|
||||
num12 ^= num17;
|
||||
num16 ^= num17;
|
||||
num17 = (num ^ num3) & 0xFFFF0000FFFF0000uL;
|
||||
num ^= num17;
|
||||
num3 ^= num17;
|
||||
num17 = (num2 ^ num4) & 0xFFFF0000FFFF00L;
|
||||
num2 ^= num17;
|
||||
num4 ^= num17;
|
||||
num17 = (num5 ^ num7) & 0xFFFF0000FFFF0000uL;
|
||||
num5 ^= num17;
|
||||
num7 ^= num17;
|
||||
num17 = (num6 ^ num8) & 0xFFFF0000FFFF00L;
|
||||
num6 ^= num17;
|
||||
num8 ^= num17;
|
||||
num17 = (num9 ^ num11) & 0xFFFF0000FFFF0000uL;
|
||||
num9 ^= num17;
|
||||
num11 ^= num17;
|
||||
num17 = (num10 ^ num12) & 0xFFFF0000FFFF00L;
|
||||
num10 ^= num17;
|
||||
num12 ^= num17;
|
||||
num17 = (num13 ^ num15) & 0xFFFF0000FFFF0000uL;
|
||||
num13 ^= num17;
|
||||
num15 ^= num17;
|
||||
num17 = (num14 ^ num16) & 0xFFFF0000FFFF00L;
|
||||
num14 ^= num17;
|
||||
num16 ^= num17;
|
||||
num17 = (num ^ num2) & 0xFF00FF00FF00FF00uL;
|
||||
num ^= num17;
|
||||
num2 ^= num17;
|
||||
num17 = (num3 ^ num4) & 0xFF00FF00FF00FF00uL;
|
||||
num3 ^= num17;
|
||||
num4 ^= num17;
|
||||
num17 = (num5 ^ num6) & 0xFF00FF00FF00FF00uL;
|
||||
num5 ^= num17;
|
||||
num6 ^= num17;
|
||||
num17 = (num7 ^ num8) & 0xFF00FF00FF00FF00uL;
|
||||
num7 ^= num17;
|
||||
num8 ^= num17;
|
||||
num17 = (num9 ^ num10) & 0xFF00FF00FF00FF00uL;
|
||||
num9 ^= num17;
|
||||
num10 ^= num17;
|
||||
num17 = (num11 ^ num12) & 0xFF00FF00FF00FF00uL;
|
||||
num11 ^= num17;
|
||||
num12 ^= num17;
|
||||
num17 = (num13 ^ num14) & 0xFF00FF00FF00FF00uL;
|
||||
num13 ^= num17;
|
||||
num14 ^= num17;
|
||||
num17 = (num15 ^ num16) & 0xFF00FF00FF00FF00uL;
|
||||
num15 ^= num17;
|
||||
num16 ^= num17;
|
||||
s[0] = num;
|
||||
s[1] = num2;
|
||||
s[2] = num3;
|
||||
s[3] = num4;
|
||||
s[4] = num5;
|
||||
s[5] = num6;
|
||||
s[6] = num7;
|
||||
s[7] = num8;
|
||||
s[8] = num9;
|
||||
s[9] = num10;
|
||||
s[10] = num11;
|
||||
s[11] = num12;
|
||||
s[12] = num13;
|
||||
s[13] = num14;
|
||||
s[14] = num15;
|
||||
s[15] = num16;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException("unsupported state size: only 512/1024 are allowed");
|
||||
}
|
||||
}
|
||||
|
||||
private void SubBytes(ulong[] s)
|
||||
{
|
||||
for (int i = 0; i < columns; i++)
|
||||
{
|
||||
ulong num = s[i];
|
||||
uint num2 = (uint)num;
|
||||
uint num3 = (uint)(num >> 32);
|
||||
byte b = S0[num2 & 0xFF];
|
||||
byte b2 = S1[(num2 >> 8) & 0xFF];
|
||||
byte b3 = S2[(num2 >> 16) & 0xFF];
|
||||
byte b4 = S3[num2 >> 24];
|
||||
num2 = (uint)(b | (b2 << 8) | (b3 << 16) | (b4 << 24));
|
||||
byte b5 = S0[num3 & 0xFF];
|
||||
byte b6 = S1[(num3 >> 8) & 0xFF];
|
||||
byte b7 = S2[(num3 >> 16) & 0xFF];
|
||||
byte b8 = S3[num3 >> 24];
|
||||
num3 = (uint)(b5 | (b6 << 8) | (b7 << 16) | (b8 << 24));
|
||||
s[i] = num2 | ((ulong)num3 << 32);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual IMemoable Copy()
|
||||
{
|
||||
return new Dstu7564Digest(this);
|
||||
}
|
||||
|
||||
public virtual void Reset(IMemoable other)
|
||||
{
|
||||
Dstu7564Digest digest = (Dstu7564Digest)other;
|
||||
CopyIn(digest);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public abstract class GeneralDigest : IDigest, IMemoable
|
||||
{
|
||||
private const int BYTE_LENGTH = 64;
|
||||
|
||||
private byte[] xBuf;
|
||||
|
||||
private int xBufOff;
|
||||
|
||||
private long byteCount;
|
||||
|
||||
public abstract string AlgorithmName { get; }
|
||||
|
||||
internal GeneralDigest()
|
||||
{
|
||||
xBuf = new byte[4];
|
||||
}
|
||||
|
||||
internal GeneralDigest(GeneralDigest t)
|
||||
{
|
||||
xBuf = new byte[t.xBuf.Length];
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
protected void CopyIn(GeneralDigest t)
|
||||
{
|
||||
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)
|
||||
{
|
||||
length = System.Math.Max(0, length);
|
||||
int i = 0;
|
||||
if (xBufOff != 0)
|
||||
{
|
||||
while (i < length)
|
||||
{
|
||||
xBuf[xBufOff++] = input[inOff + i++];
|
||||
if (xBufOff == 4)
|
||||
{
|
||||
ProcessWord(xBuf, 0);
|
||||
xBufOff = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int num = ((length - i) & -4) + i; i < num; i += 4)
|
||||
{
|
||||
ProcessWord(input, inOff + i);
|
||||
}
|
||||
while (i < length)
|
||||
{
|
||||
xBuf[xBufOff++] = input[inOff + i++];
|
||||
}
|
||||
byteCount += length;
|
||||
}
|
||||
|
||||
public void Finish()
|
||||
{
|
||||
long bitLength = byteCount << 3;
|
||||
Update(128);
|
||||
while (xBufOff != 0)
|
||||
{
|
||||
Update(0);
|
||||
}
|
||||
ProcessLength(bitLength);
|
||||
ProcessBlock();
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
byteCount = 0L;
|
||||
xBufOff = 0;
|
||||
Array.Clear(xBuf, 0, xBuf.Length);
|
||||
}
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
internal abstract void ProcessWord(byte[] input, int inOff);
|
||||
|
||||
internal abstract void ProcessLength(long bitLength);
|
||||
|
||||
internal abstract void ProcessBlock();
|
||||
|
||||
public abstract int GetDigestSize();
|
||||
|
||||
public abstract int DoFinal(byte[] output, int outOff);
|
||||
|
||||
public abstract IMemoable Copy();
|
||||
|
||||
public abstract void Reset(IMemoable t);
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Engines;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Gost3411Digest : IDigest, IMemoable
|
||||
{
|
||||
private const int DIGEST_LENGTH = 32;
|
||||
|
||||
private byte[] H = new byte[32];
|
||||
|
||||
private byte[] L = new byte[32];
|
||||
|
||||
private byte[] M = new byte[32];
|
||||
|
||||
private byte[] Sum = new byte[32];
|
||||
|
||||
private byte[][] C = MakeC();
|
||||
|
||||
private byte[] xBuf = new byte[32];
|
||||
|
||||
private int xBufOff;
|
||||
|
||||
private ulong byteCount;
|
||||
|
||||
private readonly IBlockCipher cipher = new Gost28147Engine();
|
||||
|
||||
private byte[] sBox;
|
||||
|
||||
private byte[] K = new byte[32];
|
||||
|
||||
private byte[] a = new byte[8];
|
||||
|
||||
internal short[] wS = new short[16];
|
||||
|
||||
internal short[] w_S = new short[16];
|
||||
|
||||
internal byte[] S = new byte[32];
|
||||
|
||||
internal byte[] U = new byte[32];
|
||||
|
||||
internal byte[] V = new byte[32];
|
||||
|
||||
internal byte[] W = new byte[32];
|
||||
|
||||
private static readonly byte[] C2 = new byte[32]
|
||||
{
|
||||
0, 255, 0, 255, 0, 255, 0, 255, 255, 0,
|
||||
255, 0, 255, 0, 255, 0, 0, 255, 255, 0,
|
||||
255, 0, 0, 255, 255, 0, 0, 0, 255, 255,
|
||||
0, 255
|
||||
};
|
||||
|
||||
public string AlgorithmName => "Gost3411";
|
||||
|
||||
private static byte[][] MakeC()
|
||||
{
|
||||
byte[][] array = new byte[4][];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
array[i] = new byte[32];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public Gost3411Digest()
|
||||
{
|
||||
sBox = Gost28147Engine.GetSBox("D-A");
|
||||
cipher.Init(forEncryption: true, new ParametersWithSBox(null, sBox));
|
||||
Reset();
|
||||
}
|
||||
|
||||
public Gost3411Digest(byte[] sBoxParam)
|
||||
{
|
||||
sBox = Arrays.Clone(sBoxParam);
|
||||
cipher.Init(forEncryption: true, new ParametersWithSBox(null, sBox));
|
||||
Reset();
|
||||
}
|
||||
|
||||
public Gost3411Digest(Gost3411Digest t)
|
||||
{
|
||||
Reset(t);
|
||||
}
|
||||
|
||||
public int GetDigestSize()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
public void Update(byte input)
|
||||
{
|
||||
xBuf[xBufOff++] = input;
|
||||
if (xBufOff == xBuf.Length)
|
||||
{
|
||||
sumByteArray(xBuf);
|
||||
processBlock(xBuf, 0);
|
||||
xBufOff = 0;
|
||||
}
|
||||
byteCount++;
|
||||
}
|
||||
|
||||
public void BlockUpdate(byte[] input, int inOff, int length)
|
||||
{
|
||||
while (xBufOff != 0 && length > 0)
|
||||
{
|
||||
Update(input[inOff]);
|
||||
inOff++;
|
||||
length--;
|
||||
}
|
||||
while (length > xBuf.Length)
|
||||
{
|
||||
Array.Copy(input, inOff, xBuf, 0, xBuf.Length);
|
||||
sumByteArray(xBuf);
|
||||
processBlock(xBuf, 0);
|
||||
inOff += xBuf.Length;
|
||||
length -= xBuf.Length;
|
||||
byteCount += (uint)xBuf.Length;
|
||||
}
|
||||
while (length > 0)
|
||||
{
|
||||
Update(input[inOff]);
|
||||
inOff++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] P(byte[] input)
|
||||
{
|
||||
int num = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
K[num++] = input[i];
|
||||
K[num++] = input[8 + i];
|
||||
K[num++] = input[16 + i];
|
||||
K[num++] = input[24 + i];
|
||||
}
|
||||
return K;
|
||||
}
|
||||
|
||||
private byte[] A(byte[] input)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
a[i] = (byte)(input[i] ^ input[i + 8]);
|
||||
}
|
||||
Array.Copy(input, 8, input, 0, 24);
|
||||
Array.Copy(a, 0, input, 24, 8);
|
||||
return input;
|
||||
}
|
||||
|
||||
private void E(byte[] key, byte[] s, int sOff, byte[] input, int inOff)
|
||||
{
|
||||
cipher.Init(forEncryption: true, new KeyParameter(key));
|
||||
cipher.ProcessBlock(input, inOff, s, sOff);
|
||||
}
|
||||
|
||||
private void fw(byte[] input)
|
||||
{
|
||||
cpyBytesToShort(input, wS);
|
||||
w_S[15] = (short)(wS[0] ^ wS[1] ^ wS[2] ^ wS[3] ^ wS[12] ^ wS[15]);
|
||||
Array.Copy(wS, 1, w_S, 0, 15);
|
||||
cpyShortToBytes(w_S, input);
|
||||
}
|
||||
|
||||
private void processBlock(byte[] input, int inOff)
|
||||
{
|
||||
Array.Copy(input, inOff, M, 0, 32);
|
||||
H.CopyTo(U, 0);
|
||||
M.CopyTo(V, 0);
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
W[i] = (byte)(U[i] ^ V[i]);
|
||||
}
|
||||
E(P(W), S, 0, H, 0);
|
||||
for (int j = 1; j < 4; j++)
|
||||
{
|
||||
byte[] array = A(U);
|
||||
for (int k = 0; k < 32; k++)
|
||||
{
|
||||
U[k] = (byte)(array[k] ^ C[j][k]);
|
||||
}
|
||||
V = A(A(V));
|
||||
for (int l = 0; l < 32; l++)
|
||||
{
|
||||
W[l] = (byte)(U[l] ^ V[l]);
|
||||
}
|
||||
E(P(W), S, j * 8, H, j * 8);
|
||||
}
|
||||
for (int m = 0; m < 12; m++)
|
||||
{
|
||||
fw(S);
|
||||
}
|
||||
for (int n = 0; n < 32; n++)
|
||||
{
|
||||
S[n] ^= M[n];
|
||||
}
|
||||
fw(S);
|
||||
for (int num = 0; num < 32; num++)
|
||||
{
|
||||
S[num] = (byte)(H[num] ^ S[num]);
|
||||
}
|
||||
for (int num2 = 0; num2 < 61; num2++)
|
||||
{
|
||||
fw(S);
|
||||
}
|
||||
Array.Copy(S, 0, H, 0, H.Length);
|
||||
}
|
||||
|
||||
private void finish()
|
||||
{
|
||||
ulong n = byteCount * 8;
|
||||
Pack.UInt64_To_LE(n, L);
|
||||
while (xBufOff != 0)
|
||||
{
|
||||
Update(0);
|
||||
}
|
||||
processBlock(L, 0);
|
||||
processBlock(Sum, 0);
|
||||
}
|
||||
|
||||
public int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
finish();
|
||||
H.CopyTo(output, outOff);
|
||||
Reset();
|
||||
return 32;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
byteCount = 0uL;
|
||||
xBufOff = 0;
|
||||
Array.Clear(H, 0, H.Length);
|
||||
Array.Clear(L, 0, L.Length);
|
||||
Array.Clear(M, 0, M.Length);
|
||||
Array.Clear(C[1], 0, C[1].Length);
|
||||
Array.Clear(C[3], 0, C[3].Length);
|
||||
Array.Clear(Sum, 0, Sum.Length);
|
||||
Array.Clear(xBuf, 0, xBuf.Length);
|
||||
C2.CopyTo(C[2], 0);
|
||||
}
|
||||
|
||||
private void sumByteArray(byte[] input)
|
||||
{
|
||||
int num = 0;
|
||||
for (int i = 0; i != Sum.Length; i++)
|
||||
{
|
||||
int num2 = (Sum[i] & 0xFF) + (input[i] & 0xFF) + num;
|
||||
Sum[i] = (byte)num2;
|
||||
num = num2 >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
private static void cpyBytesToShort(byte[] S, short[] wS)
|
||||
{
|
||||
for (int i = 0; i < S.Length / 2; i++)
|
||||
{
|
||||
wS[i] = (short)(((S[i * 2 + 1] << 8) & 0xFF00) | (S[i * 2] & 0xFF));
|
||||
}
|
||||
}
|
||||
|
||||
private static void cpyShortToBytes(short[] wS, byte[] S)
|
||||
{
|
||||
for (int i = 0; i < S.Length / 2; i++)
|
||||
{
|
||||
S[i * 2 + 1] = (byte)(wS[i] >> 8);
|
||||
S[i * 2] = (byte)wS[i];
|
||||
}
|
||||
}
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
public IMemoable Copy()
|
||||
{
|
||||
return new Gost3411Digest(this);
|
||||
}
|
||||
|
||||
public void Reset(IMemoable other)
|
||||
{
|
||||
Gost3411Digest gost3411Digest = (Gost3411Digest)other;
|
||||
sBox = gost3411Digest.sBox;
|
||||
cipher.Init(forEncryption: true, new ParametersWithSBox(null, sBox));
|
||||
Reset();
|
||||
Array.Copy(gost3411Digest.H, 0, H, 0, gost3411Digest.H.Length);
|
||||
Array.Copy(gost3411Digest.L, 0, L, 0, gost3411Digest.L.Length);
|
||||
Array.Copy(gost3411Digest.M, 0, M, 0, gost3411Digest.M.Length);
|
||||
Array.Copy(gost3411Digest.Sum, 0, Sum, 0, gost3411Digest.Sum.Length);
|
||||
Array.Copy(gost3411Digest.C[1], 0, C[1], 0, gost3411Digest.C[1].Length);
|
||||
Array.Copy(gost3411Digest.C[2], 0, C[2], 0, gost3411Digest.C[2].Length);
|
||||
Array.Copy(gost3411Digest.C[3], 0, C[3], 0, gost3411Digest.C[3].Length);
|
||||
Array.Copy(gost3411Digest.xBuf, 0, xBuf, 0, gost3411Digest.xBuf.Length);
|
||||
xBufOff = gost3411Digest.xBufOff;
|
||||
byteCount = gost3411Digest.byteCount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,722 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public abstract class Gost3411_2012Digest : IDigest, IMemoable
|
||||
{
|
||||
private readonly byte[] IV = new byte[64];
|
||||
|
||||
private readonly byte[] N = new byte[64];
|
||||
|
||||
private readonly byte[] Sigma = new byte[64];
|
||||
|
||||
private readonly byte[] Ki = new byte[64];
|
||||
|
||||
private readonly byte[] m = new byte[64];
|
||||
|
||||
private readonly byte[] h = new byte[64];
|
||||
|
||||
private readonly byte[] tmp = new byte[64];
|
||||
|
||||
private readonly byte[] block = new byte[64];
|
||||
|
||||
private int bOff = 64;
|
||||
|
||||
private static readonly byte[][] C = new byte[12][]
|
||||
{
|
||||
new byte[64]
|
||||
{
|
||||
177, 8, 91, 218, 30, 202, 218, 233, 235, 203,
|
||||
47, 129, 192, 101, 124, 31, 47, 106, 118, 67,
|
||||
46, 69, 208, 22, 113, 78, 184, 141, 117, 133,
|
||||
196, 252, 75, 124, 224, 145, 146, 103, 105, 1,
|
||||
162, 66, 42, 8, 164, 96, 211, 21, 5, 118,
|
||||
116, 54, 204, 116, 77, 35, 221, 128, 101, 89,
|
||||
242, 166, 69, 7
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
111, 163, 181, 138, 169, 157, 47, 26, 79, 227,
|
||||
157, 70, 15, 112, 181, 215, 243, 254, 234, 114,
|
||||
10, 35, 43, 152, 97, 213, 94, 15, 22, 181,
|
||||
1, 49, 154, 181, 23, 107, 18, 214, 153, 88,
|
||||
92, 181, 97, 194, 219, 10, 167, 202, 85, 221,
|
||||
162, 27, 215, 203, 205, 86, 230, 121, 4, 112,
|
||||
33, 177, 155, 183
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
245, 116, 220, 172, 43, 206, 47, 199, 10, 57,
|
||||
252, 40, 106, 61, 132, 53, 6, 241, 94, 95,
|
||||
82, 156, 31, 139, 242, 234, 117, 20, 177, 41,
|
||||
123, 123, 211, 226, 15, 228, 144, 53, 158, 177,
|
||||
193, 201, 58, 55, 96, 98, 219, 9, 194, 182,
|
||||
244, 67, 134, 122, 219, 49, 153, 30, 150, 245,
|
||||
10, 186, 10, 178
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
239, 31, 223, 179, 232, 21, 102, 210, 249, 72,
|
||||
225, 160, 93, 113, 228, 221, 72, 142, 133, 126,
|
||||
51, 92, 60, 125, 157, 114, 28, 173, 104, 94,
|
||||
53, 63, 169, 215, 44, 130, 237, 3, 214, 117,
|
||||
216, 183, 19, 51, 147, 82, 3, 190, 52, 83,
|
||||
234, 161, 147, 232, 55, 241, 34, 12, 190, 188,
|
||||
132, 227, 209, 46
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
75, 234, 107, 172, 173, 71, 71, 153, 154, 63,
|
||||
65, 12, 108, 169, 35, 99, 127, 21, 28, 31,
|
||||
22, 134, 16, 74, 53, 158, 53, 215, 128, 15,
|
||||
255, 189, 191, 205, 23, 71, 37, 58, 245, 163,
|
||||
223, 255, 0, 183, 35, 39, 26, 22, 122, 86,
|
||||
162, 126, 169, 234, 99, 245, 96, 23, 88, 253,
|
||||
124, 108, 254, 87
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
174, 79, 174, 174, 29, 58, 211, 217, 111, 164,
|
||||
195, 59, 122, 48, 57, 192, 45, 102, 196, 249,
|
||||
81, 66, 164, 108, 24, 127, 154, 180, 154, 240,
|
||||
142, 198, 207, 250, 166, 183, 28, 154, 183, 180,
|
||||
10, 242, 31, 102, 194, 190, 198, 182, 191, 113,
|
||||
197, 114, 54, 144, 79, 53, 250, 104, 64, 122,
|
||||
70, 100, 125, 110
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
244, 199, 14, 22, 238, 170, 197, 236, 81, 172,
|
||||
134, 254, 191, 36, 9, 84, 57, 158, 198, 199,
|
||||
230, 191, 135, 201, 211, 71, 62, 51, 25, 122,
|
||||
147, 201, 9, 146, 171, 197, 45, 130, 44, 55,
|
||||
6, 71, 105, 131, 40, 74, 5, 4, 53, 23,
|
||||
69, 76, 162, 60, 74, 243, 136, 134, 86, 77,
|
||||
58, 20, 212, 147
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
155, 31, 91, 66, 77, 147, 201, 167, 3, 231,
|
||||
170, 2, 12, 110, 65, 65, 78, 183, 248, 113,
|
||||
156, 54, 222, 30, 137, 180, 68, 59, 77, 219,
|
||||
196, 154, 244, 137, 43, 203, 146, 155, 6, 144,
|
||||
105, 209, 141, 43, 209, 165, 196, 47, 54, 172,
|
||||
194, 53, 89, 81, 168, 217, 164, 127, 13, 212,
|
||||
191, 2, 231, 30
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
55, 143, 90, 84, 22, 49, 34, 155, 148, 76,
|
||||
154, 216, 236, 22, 95, 222, 58, 125, 58, 27,
|
||||
37, 137, 66, 36, 60, 217, 85, 183, 224, 13,
|
||||
9, 132, 128, 10, 68, 11, 219, 178, 206, 177,
|
||||
123, 43, 138, 154, 166, 7, 156, 84, 14, 56,
|
||||
220, 146, 203, 31, 42, 96, 114, 97, 68, 81,
|
||||
131, 35, 90, 219
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
171, 190, 222, 166, 128, 5, 111, 82, 56, 42,
|
||||
229, 72, 178, 228, 243, 243, 137, 65, 231, 28,
|
||||
255, 138, 120, 219, 31, 255, 225, 138, 27, 51,
|
||||
97, 3, 159, 231, 103, 2, 175, 105, 51, 75,
|
||||
122, 30, 108, 48, 59, 118, 82, 244, 54, 152,
|
||||
250, 209, 21, 59, 182, 195, 116, 180, 199, 251,
|
||||
152, 69, 156, 237
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
123, 205, 158, 208, 239, 200, 137, 251, 48, 2,
|
||||
198, 205, 99, 90, 254, 148, 216, 250, 107, 187,
|
||||
235, 171, 7, 97, 32, 1, 128, 33, 20, 132,
|
||||
102, 121, 138, 29, 113, 239, 234, 72, 185, 202,
|
||||
239, 186, 205, 29, 125, 71, 110, 152, 222, 162,
|
||||
89, 74, 192, 111, 216, 93, 107, 202, 164, 205,
|
||||
129, 243, 45, 27
|
||||
},
|
||||
new byte[64]
|
||||
{
|
||||
55, 142, 231, 103, 241, 22, 49, 186, 210, 19,
|
||||
128, 176, 4, 73, 177, 122, 205, 164, 60, 50,
|
||||
188, 223, 29, 119, 248, 32, 18, 212, 48, 33,
|
||||
159, 155, 93, 128, 239, 157, 24, 145, 204, 134,
|
||||
231, 29, 164, 170, 136, 225, 40, 82, 250, 244,
|
||||
23, 213, 217, 178, 27, 153, 72, 188, 146, 74,
|
||||
241, 27, 215, 32
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly byte[] Zero;
|
||||
|
||||
private static readonly ulong[][] T;
|
||||
|
||||
public abstract string AlgorithmName { get; }
|
||||
|
||||
protected Gost3411_2012Digest(byte[] IV)
|
||||
{
|
||||
Array.Copy(IV, this.IV, 64);
|
||||
Array.Copy(IV, h, 64);
|
||||
}
|
||||
|
||||
public abstract IMemoable Copy();
|
||||
|
||||
public virtual int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
int num = 64 - bOff;
|
||||
for (int i = 0; i != 64 - num; i++)
|
||||
{
|
||||
m[i] = 0;
|
||||
}
|
||||
m[63 - num] = 1;
|
||||
if (bOff != 64)
|
||||
{
|
||||
Array.Copy(block, bOff, m, 64 - num, num);
|
||||
}
|
||||
g_N(h, N, m);
|
||||
addMod512(N, num * 8);
|
||||
addMod512(Sigma, m);
|
||||
g_N(h, Zero, N);
|
||||
g_N(h, Zero, Sigma);
|
||||
reverse(h, tmp);
|
||||
Array.Copy(tmp, 0, output, outOff, 64);
|
||||
Reset();
|
||||
return 64;
|
||||
}
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public abstract int GetDigestSize();
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
bOff = 64;
|
||||
Arrays.Fill(N, 0);
|
||||
Arrays.Fill(Sigma, 0);
|
||||
Array.Copy(IV, 0, h, 0, 64);
|
||||
Arrays.Fill(block, 0);
|
||||
}
|
||||
|
||||
public void Reset(IMemoable other)
|
||||
{
|
||||
Gost3411_2012Digest gost3411_2012Digest = (Gost3411_2012Digest)other;
|
||||
Array.Copy(gost3411_2012Digest.IV, 0, IV, 0, 64);
|
||||
Array.Copy(gost3411_2012Digest.N, 0, N, 0, 64);
|
||||
Array.Copy(gost3411_2012Digest.Sigma, 0, Sigma, 0, 64);
|
||||
Array.Copy(gost3411_2012Digest.Ki, 0, Ki, 0, 64);
|
||||
Array.Copy(gost3411_2012Digest.m, 0, m, 0, 64);
|
||||
Array.Copy(gost3411_2012Digest.h, 0, h, 0, 64);
|
||||
Array.Copy(gost3411_2012Digest.block, 0, block, 0, 64);
|
||||
bOff = gost3411_2012Digest.bOff;
|
||||
}
|
||||
|
||||
public void Update(byte input)
|
||||
{
|
||||
block[--bOff] = input;
|
||||
if (bOff == 0)
|
||||
{
|
||||
g_N(h, N, block);
|
||||
addMod512(N, 512);
|
||||
addMod512(Sigma, block);
|
||||
bOff = 64;
|
||||
}
|
||||
}
|
||||
|
||||
public void BlockUpdate(byte[] input, int inOff, int len)
|
||||
{
|
||||
while (bOff != 64 && len > 0)
|
||||
{
|
||||
Update(input[inOff++]);
|
||||
len--;
|
||||
}
|
||||
while (len >= 64)
|
||||
{
|
||||
Array.Copy(input, inOff, tmp, 0, 64);
|
||||
reverse(tmp, block);
|
||||
g_N(h, N, block);
|
||||
addMod512(N, 512);
|
||||
addMod512(Sigma, block);
|
||||
len -= 64;
|
||||
inOff += 64;
|
||||
}
|
||||
while (len > 0)
|
||||
{
|
||||
Update(input[inOff++]);
|
||||
len--;
|
||||
}
|
||||
}
|
||||
|
||||
private void F(byte[] V)
|
||||
{
|
||||
ulong[] array = new ulong[8];
|
||||
ulong num = 0uL;
|
||||
num ^= T[0][V[56] & 0xFF];
|
||||
num ^= T[1][V[48] & 0xFF];
|
||||
num ^= T[2][V[40] & 0xFF];
|
||||
num ^= T[3][V[32] & 0xFF];
|
||||
num ^= T[4][V[24] & 0xFF];
|
||||
num ^= T[5][V[16] & 0xFF];
|
||||
num ^= T[6][V[8] & 0xFF];
|
||||
num ^= T[7][V[0] & 0xFF];
|
||||
array[0] = num;
|
||||
num = 0uL;
|
||||
num ^= T[0][V[57] & 0xFF];
|
||||
num ^= T[1][V[49] & 0xFF];
|
||||
num ^= T[2][V[41] & 0xFF];
|
||||
num ^= T[3][V[33] & 0xFF];
|
||||
num ^= T[4][V[25] & 0xFF];
|
||||
num ^= T[5][V[17] & 0xFF];
|
||||
num ^= T[6][V[9] & 0xFF];
|
||||
num ^= T[7][V[1] & 0xFF];
|
||||
array[1] = num;
|
||||
num = 0uL;
|
||||
num ^= T[0][V[58] & 0xFF];
|
||||
num ^= T[1][V[50] & 0xFF];
|
||||
num ^= T[2][V[42] & 0xFF];
|
||||
num ^= T[3][V[34] & 0xFF];
|
||||
num ^= T[4][V[26] & 0xFF];
|
||||
num ^= T[5][V[18] & 0xFF];
|
||||
num ^= T[6][V[10] & 0xFF];
|
||||
num ^= T[7][V[2] & 0xFF];
|
||||
array[2] = num;
|
||||
num = 0uL;
|
||||
num ^= T[0][V[59] & 0xFF];
|
||||
num ^= T[1][V[51] & 0xFF];
|
||||
num ^= T[2][V[43] & 0xFF];
|
||||
num ^= T[3][V[35] & 0xFF];
|
||||
num ^= T[4][V[27] & 0xFF];
|
||||
num ^= T[5][V[19] & 0xFF];
|
||||
num ^= T[6][V[11] & 0xFF];
|
||||
num ^= T[7][V[3] & 0xFF];
|
||||
array[3] = num;
|
||||
num = 0uL;
|
||||
num ^= T[0][V[60] & 0xFF];
|
||||
num ^= T[1][V[52] & 0xFF];
|
||||
num ^= T[2][V[44] & 0xFF];
|
||||
num ^= T[3][V[36] & 0xFF];
|
||||
num ^= T[4][V[28] & 0xFF];
|
||||
num ^= T[5][V[20] & 0xFF];
|
||||
num ^= T[6][V[12] & 0xFF];
|
||||
num ^= T[7][V[4] & 0xFF];
|
||||
array[4] = num;
|
||||
num = 0uL;
|
||||
num ^= T[0][V[61] & 0xFF];
|
||||
num ^= T[1][V[53] & 0xFF];
|
||||
num ^= T[2][V[45] & 0xFF];
|
||||
num ^= T[3][V[37] & 0xFF];
|
||||
num ^= T[4][V[29] & 0xFF];
|
||||
num ^= T[5][V[21] & 0xFF];
|
||||
num ^= T[6][V[13] & 0xFF];
|
||||
num ^= T[7][V[5] & 0xFF];
|
||||
array[5] = num;
|
||||
num = 0uL;
|
||||
num ^= T[0][V[62] & 0xFF];
|
||||
num ^= T[1][V[54] & 0xFF];
|
||||
num ^= T[2][V[46] & 0xFF];
|
||||
num ^= T[3][V[38] & 0xFF];
|
||||
num ^= T[4][V[30] & 0xFF];
|
||||
num ^= T[5][V[22] & 0xFF];
|
||||
num ^= T[6][V[14] & 0xFF];
|
||||
num ^= T[7][V[6] & 0xFF];
|
||||
array[6] = num;
|
||||
num = 0uL;
|
||||
num ^= T[0][V[63] & 0xFF];
|
||||
num ^= T[1][V[55] & 0xFF];
|
||||
num ^= T[2][V[47] & 0xFF];
|
||||
num ^= T[3][V[39] & 0xFF];
|
||||
num ^= T[4][V[31] & 0xFF];
|
||||
num ^= T[5][V[23] & 0xFF];
|
||||
num ^= T[6][V[15] & 0xFF];
|
||||
num ^= T[7][V[7] & 0xFF];
|
||||
array[7] = num;
|
||||
num = array[0];
|
||||
V[7] = (byte)(num >> 56);
|
||||
V[6] = (byte)(num >> 48);
|
||||
V[5] = (byte)(num >> 40);
|
||||
V[4] = (byte)(num >> 32);
|
||||
V[3] = (byte)(num >> 24);
|
||||
V[2] = (byte)(num >> 16);
|
||||
V[1] = (byte)(num >> 8);
|
||||
V[0] = (byte)num;
|
||||
num = array[1];
|
||||
V[15] = (byte)(num >> 56);
|
||||
V[14] = (byte)(num >> 48);
|
||||
V[13] = (byte)(num >> 40);
|
||||
V[12] = (byte)(num >> 32);
|
||||
V[11] = (byte)(num >> 24);
|
||||
V[10] = (byte)(num >> 16);
|
||||
V[9] = (byte)(num >> 8);
|
||||
V[8] = (byte)num;
|
||||
num = array[2];
|
||||
V[23] = (byte)(num >> 56);
|
||||
V[22] = (byte)(num >> 48);
|
||||
V[21] = (byte)(num >> 40);
|
||||
V[20] = (byte)(num >> 32);
|
||||
V[19] = (byte)(num >> 24);
|
||||
V[18] = (byte)(num >> 16);
|
||||
V[17] = (byte)(num >> 8);
|
||||
V[16] = (byte)num;
|
||||
num = array[3];
|
||||
V[31] = (byte)(num >> 56);
|
||||
V[30] = (byte)(num >> 48);
|
||||
V[29] = (byte)(num >> 40);
|
||||
V[28] = (byte)(num >> 32);
|
||||
V[27] = (byte)(num >> 24);
|
||||
V[26] = (byte)(num >> 16);
|
||||
V[25] = (byte)(num >> 8);
|
||||
V[24] = (byte)num;
|
||||
num = array[4];
|
||||
V[39] = (byte)(num >> 56);
|
||||
V[38] = (byte)(num >> 48);
|
||||
V[37] = (byte)(num >> 40);
|
||||
V[36] = (byte)(num >> 32);
|
||||
V[35] = (byte)(num >> 24);
|
||||
V[34] = (byte)(num >> 16);
|
||||
V[33] = (byte)(num >> 8);
|
||||
V[32] = (byte)num;
|
||||
num = array[5];
|
||||
V[47] = (byte)(num >> 56);
|
||||
V[46] = (byte)(num >> 48);
|
||||
V[45] = (byte)(num >> 40);
|
||||
V[44] = (byte)(num >> 32);
|
||||
V[43] = (byte)(num >> 24);
|
||||
V[42] = (byte)(num >> 16);
|
||||
V[41] = (byte)(num >> 8);
|
||||
V[40] = (byte)num;
|
||||
num = array[6];
|
||||
V[55] = (byte)(num >> 56);
|
||||
V[54] = (byte)(num >> 48);
|
||||
V[53] = (byte)(num >> 40);
|
||||
V[52] = (byte)(num >> 32);
|
||||
V[51] = (byte)(num >> 24);
|
||||
V[50] = (byte)(num >> 16);
|
||||
V[49] = (byte)(num >> 8);
|
||||
V[48] = (byte)num;
|
||||
num = array[7];
|
||||
V[63] = (byte)(num >> 56);
|
||||
V[62] = (byte)(num >> 48);
|
||||
V[61] = (byte)(num >> 40);
|
||||
V[60] = (byte)(num >> 32);
|
||||
V[59] = (byte)(num >> 24);
|
||||
V[58] = (byte)(num >> 16);
|
||||
V[57] = (byte)(num >> 8);
|
||||
V[56] = (byte)num;
|
||||
}
|
||||
|
||||
private void xor512(byte[] A, byte[] B)
|
||||
{
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
byte[] array2;
|
||||
byte[] array = (array2 = A);
|
||||
int num = i;
|
||||
nint num2 = num;
|
||||
array[num] = (byte)(array2[num2] ^ B[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void E(byte[] K, byte[] m)
|
||||
{
|
||||
Array.Copy(K, 0, Ki, 0, 64);
|
||||
xor512(K, m);
|
||||
F(K);
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
xor512(Ki, C[i]);
|
||||
F(Ki);
|
||||
xor512(K, Ki);
|
||||
F(K);
|
||||
}
|
||||
xor512(Ki, C[11]);
|
||||
F(Ki);
|
||||
xor512(K, Ki);
|
||||
}
|
||||
|
||||
private void g_N(byte[] h, byte[] N, byte[] m)
|
||||
{
|
||||
Array.Copy(h, 0, tmp, 0, 64);
|
||||
xor512(h, N);
|
||||
F(h);
|
||||
E(h, m);
|
||||
xor512(h, tmp);
|
||||
xor512(h, m);
|
||||
}
|
||||
|
||||
private void addMod512(byte[] A, int num)
|
||||
{
|
||||
int num2 = (A[63] & 0xFF) + (num & 0xFF);
|
||||
A[63] = (byte)num2;
|
||||
num2 = (A[62] & 0xFF) + ((num >> 8) & 0xFF) + (num2 >> 8);
|
||||
A[62] = (byte)num2;
|
||||
int num3 = 61;
|
||||
while (num3 >= 0 && num2 > 0)
|
||||
{
|
||||
num2 = (A[num3] & 0xFF) + (num2 >> 8);
|
||||
A[num3] = (byte)num2;
|
||||
num3--;
|
||||
}
|
||||
}
|
||||
|
||||
private void addMod512(byte[] A, byte[] B)
|
||||
{
|
||||
int num = 0;
|
||||
for (int num2 = 63; num2 >= 0; num2--)
|
||||
{
|
||||
num = (A[num2] & 0xFF) + (B[num2] & 0xFF) + (num >> 8);
|
||||
A[num2] = (byte)num;
|
||||
}
|
||||
}
|
||||
|
||||
private void reverse(byte[] src, byte[] dst)
|
||||
{
|
||||
int num = src.Length;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
dst[num - 1 - i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
static Gost3411_2012Digest()
|
||||
{
|
||||
byte[] zero = new byte[64];
|
||||
Zero = zero;
|
||||
T = new ulong[8][]
|
||||
{
|
||||
new ulong[256]
|
||||
{
|
||||
16643191358083899344uL, 2703135593145367062uL, 14432313314890392744uL, 6577092334268629354uL, 806964168861892974uL, 12383271304659295334uL, 17732807706536339062uL, 17716047611503416651uL, 5215999108449717233uL, 18400690592850740677uL,
|
||||
14664421492831770517uL, 7409386412115095689uL, 3849627103271945136uL, 8988319201874450849uL, 3938119337751376013uL, 11436513915861524438uL, 10023317675342802487uL, 11299449278894865675uL, 13550338097771745114uL, 16515794415152327917uL,
|
||||
14898690228356210642uL, 17039395261956034398uL, 13352261127337576221uL, 10097173395646645421uL, 8519831221648263471uL, 6380786457702773335uL, 4606327678483665726uL, 1135139788101916873uL, 17150000018454982019uL, 1220450159802546598uL,
|
||||
6759235690777098768uL, 5340123591806085420uL, 6034809048673841977uL, 13039342382114553097uL, 6896344311240562893uL, 16756255438728353529uL, 9184934662348565148uL, 14262951085445095100uL, 11989701146933847666uL, 3364644269219363704uL,
|
||||
989048157634869780uL, 9390583993925520772uL, 3387584785362250392uL, 6665082552186727408uL, 8806730920978768603uL, 9502751530347994212uL, 14947525897166917170uL, 9613964225661560606uL, 13062563757722791145uL, 13330165100546479869uL,
|
||||
2007762480278943944uL, 7071029175581714734uL, 18201297078263772920uL, 11348284945966902507uL, 5517131305049330262uL, 2524355749569298796uL, 3276936053954857029uL, 17613168268544492715uL, 13672639287818444474uL, 4227838725751020409uL,
|
||||
17337927304403721484uL, 2880731531503622347uL, 9899166798150700266uL, 1904883134495025448uL, 10431738646323369727uL, 4850405589464713887uL, 17844694253179975574uL, 2081972218582700626uL, 1379356218675464859uL, 11936901258434843983uL,
|
||||
3166351970529817407uL, 15521334050161542599uL, 12092580492986202002uL, 15771347623125549011uL, 9700811178911405091uL, 4095269026725968292uL, 7284836791436182452uL, 178206167350026973uL, 9859056374997736714uL, 10596801556360226242uL,
|
||||
5686309239594266763uL, 3626867272058218794uL, 4695292606739097666uL, 12861765287137887859uL, 7805587275216445447uL, 6553870956925915274uL, 2247080073069027695uL, 14085863101410174406uL, 4136504802722867268uL, 2992705483290644962uL,
|
||||
4655464135170259362uL, 16805373066242361113uL, 867873424238963700uL, 6139766898342725699uL, 5048711494641582808uL, 2360957084007330385uL, 7917754814463914471uL, 11594761360985693448uL, 8900603062938514235uL, 4819584321579539327uL,
|
||||
15611174550416907534uL, 14284208185211612545uL, 2409792751347803057uL, 7449496838093054313uL, 2608138101170875382uL, 15357211532675213082uL, 6775169570724432173uL, 2898833334747545602uL, 10370594140041967504uL, 1717647244194337596uL,
|
||||
16173369581285336234uL, 8669102231478190086uL, 7938185699155198682uL, 9733039751760463299uL, 3969222566346957165uL, 12457959604312733436uL, 9134972545477524348uL, 13884760396816717563uL, 18002934140551462591uL, 8321595681021526376uL,
|
||||
3740161260836255946uL, 12223660219698249403uL, 16465551444743798029uL, 10257300151532365424uL, 5892660270079857124uL, 2502541675832561804uL, 15642277772978588910uL, 3575476887658224151uL, 15246058200794700896uL, 669897467106812851uL,
|
||||
11238190422791214993uL, 14752624989210410255uL, 3809516679850545744uL, 5718256960103440747uL, 16113790886966425492uL, 2758712437335984427uL, 13819266239833930855uL, 15989664336639546697uL, 4334551115747581955uL, 10481700764928886559uL,
|
||||
7539375937215052192uL, 13153907711413100500uL, 1449546416188301313uL, 10970082038091293868uL, 7253733569142936148uL, 14035900984807568422uL, 4494160142329627358uL, 5797380680492875780uL, 5033684639528710629uL, 6942380200648117235uL,
|
||||
18135530224823884898uL, 11626709078934113512uL, 5452010138718157004uL, 646676091767009875uL, 13907700920084023067uL, 11458327989329825334uL, 471514214048988026uL, 17134674851811450558uL, 8614828720478738639uL, 3471190102295415799uL,
|
||||
10201460180741018957uL, 17898929444480167775uL, 16929928319467713572uL, 12279266611417189766uL, 11065079529797350732uL, 0uL, 17378882219737664748uL, 8143953700710785973uL, 12621352907304863169uL, 10952011996134456421uL,
|
||||
1847633384726895125uL, 10773808170632978104uL, 15876370350422262953uL, 10679936021821443928uL, 9235497396103343961uL, 14142057341829074780uL, 18022518333658336642uL, 17502585284089954257uL, 7698943044753169277uL, 5558086220651709366uL,
|
||||
273485755470967613uL, 16009504095842346612uL, 3045458228384031455uL, 8041346034719003450uL, 15324982954333320954uL, 13489933794196071872uL, 10831118253720235397uL, 16952024345057011140uL, 378507382706538567uL, 11825014717556671663uL,
|
||||
16409080926193522583uL, 9338657737701047993uL, 12581524441769923617uL, 17534533004330692145uL, 7175315966437357774uL, 5161723385538695992uL, 11755314076501405237uL, 8789995975362646502uL, 122301190315135456uL, 1339527752872090491uL,
|
||||
8500289773969701394uL, 15811458049371942451uL, 2206125151973814415uL, 5912507865751560921uL, 16287906185945826935uL, 18369869324697130021uL, 14569423993732859509uL, 7055674186596964883uL, 16666412735158177328uL, 3226973935617776037uL,
|
||||
1613642550683796188uL, 12110648323039866715uL, 2113919936262685618uL, 13204150689214484020uL, 15014857054700793693uL, 18241125550101047064uL, 6290905146667117214uL, 520631834711206554uL, 6090649271097153955uL, 6268809121346255742uL,
|
||||
13723986651981426055uL, 9011259725410191425uL, 4260067298331642521uL, 7571604515825379392uL, 12488780875022903068uL, 12805342026244830542uL, 4929679943725850629uL, 1562558313115120097uL, 8378270681804975090uL, 6431029428379739063uL,
|
||||
17272301201645698147uL, 7740178818457750173uL, 4437711457076851171uL, 11714359155137757141uL, 1735746844117158901uL, 1251271430781151302uL, 13440816173802288160uL, 15127024593679826621uL, 12684167292580488366uL, 9572728449396225790uL,
|
||||
8122139634094273109uL, 1040986648309745961uL, 356411355647007143uL, 756721191328944270uL, 5318878451677075985uL, 9992214447015657431uL, 14774439056095358191uL, 14554332407323555144uL, 10573861039948903458uL, 14378080326902922337uL,
|
||||
16267522719607272778uL, 15142897865499331968uL, 11116171328892012145uL, 12955918427198494611uL, 8272760012479254664uL, 15480098276725396519uL
|
||||
},
|
||||
new ulong[256]
|
||||
{
|
||||
14416488623970932190uL, 7346976492199675417uL, 17820627941079412291uL, 9627885164147495734uL, 6533467991705271684uL, 17998565102924987645uL, 11682290849618289423uL, 14822454089690596717uL, 9241203884170920837uL, 12861281897341358396uL,
|
||||
11016838668432197665uL, 13790417110750001176uL, 1151735774811599048uL, 12294974454994705048uL, 6942284815962019498uL, 17743186425950817333uL, 3304311495801540674uL, 13615607175011632002uL, 7559468737934159677uL, 12086978407351415740uL,
|
||||
2957424603572281991uL, 13249085212744581519uL, 15637041785948145051uL, 15490736964426020179uL, 15379540838187847369uL, 16875309257069950292uL, 8085181091649676441uL, 14854792058562395895uL, 18236790505793211960uL, 7642183762405766865uL,
|
||||
6618156441656008690uL, 14625287379506105394uL, 12725675947919526096uL, 6768646983239759067uL, 1229560361235927109uL, 2545497942825370364uL, 14198931498357636346uL, 8332055718082846467uL, 9018811952317763005uL, 4566156016530439069uL,
|
||||
9578872965805076800uL, 4447555131281990257uL, 1889868047608435272uL, 9132310989383824935uL, 8423405394594584156uL, 1791576812070341540uL, 895921998879640402uL, 14310611323784447840uL, 8686043850126826766uL, 18187216356076809294uL,
|
||||
3505479608743889749uL, 3164974344323824491uL, 15983355795994687326uL, 11065428791749044823uL, 1491256427646959862uL, 13524521346665040605uL, 5832729293860314623uL, 16778152971070057656uL, 5588041959860897512uL, 13969351553252232767uL,
|
||||
8960651507453538251uL, 3404044757246527918uL, 7427396029290209269uL, 1567782000193888896uL, 2125332809319160599uL, 15750446333599546881uL, 9762612037615848154uL, 14665011075415780932uL, 405965478745608371uL, 1334608620921465823uL,
|
||||
10283812314525356347uL, 6009835698019100261uL, 6362838478626120808uL, 15531164210339026725uL, 12192858250690617602uL, 10021977722754318728uL, 15045784853695487610uL, 5388605995385671607uL, 4789436484882904608uL, 8273825248612433269uL,
|
||||
6807803589745610561uL, 17643602969366402521uL, 10402470611175420342uL, 9487505662496421919uL, 13884311246691511369uL, 11599311963427125987uL, 11828896870259984422uL, 12530171073360712647uL, 12569865343065303133uL, 14159137227003829900uL,
|
||||
13058444037354018915uL, 447961557886364457uL, 11640371804876806293uL, 7989344413684106260uL, 7745519667033183399uL, 15284366481134480575uL, 16558308431455503772uL, 11775845520284565881uL, 5873227033075236745uL, 18442457284438988756uL,
|
||||
11331596615082596498uL, 2021362311995275617uL, 17399916748381652330uL, 11098401108231983565uL, 4652678544566382540uL, 1850721214614677970uL, 3779734978877634960uL, 16220639879209580377uL, 13354894618632655665uL, 10461614931578557376uL,
|
||||
1609153642657618202uL, 4480481336861891051uL, 9972894948967769086uL, 10111053643493542103uL, 4986581067319345023uL, 209097870346312172uL, 16170362179490862383uL, 13999482202363688357uL, 7798271984477724152uL, 7243570012128126063uL,
|
||||
15113725370733198348uL, 12902693100934476618uL, 9428713116562070121uL, 11255071236346149604uL, 18037622684799010663uL, 11445008741517796104uL, 13269290432258683207uL, 11202301361362088891uL, 14405433630425769238uL, 1180970181547717171uL,
|
||||
5176105366933055123uL, 7188535108749356336uL, 3071419591516346653uL, 8871593212975408788uL, 7377047836268559747uL, 745784333737205883uL, 523712867556149599uL, 3218003841565405748uL, 2276692251301888763uL, 4042724623974101698uL,
|
||||
6062869490421444410uL, 1668368207247227756uL, 18339543398465779106uL, 2916365256580759793uL, 17701763194650376111uL, 9835873103984114194uL, 6147487227497352524uL, 16084205907180383922uL, 347243151226876613uL, 6999741710823961820uL,
|
||||
2806071973676585551uL, 9658008234483460268uL, 17263250852726433255uL, 3821216675772636134uL, 16657742647079378032uL, 15229027975163028960uL, 16016335965578415300uL, 10572801009443498074uL, 17296932700355831580uL, 13696158890081409646uL,
|
||||
17554522822051683462uL, 5286400504730760237uL, 7609746906341231947uL, 15898737839338493224uL, 944934528471361828uL, 0uL, 6430778939292435998uL, 3336736409998420952uL, 7875361642996334478uL, 16600215533801848326uL,
|
||||
8821948844834997474uL, 12436686564748095921uL, 706136312374746081uL, 9940546931731077220uL, 8606606803205598662uL, 6252543065422558934uL, 258180561991695258uL, 3932361041049477244uL, 2228031909561065613uL, 3591083712976693539uL,
|
||||
8046871333151188578uL, 4829160237163942998uL, 12381352628294170862uL, 12610854471631768107uL, 4380598834454315015uL, 10649256363573758508uL, 14068055968846895059uL, 5548248045526197406uL, 12819864006535506598uL, 4026619618737144330uL,
|
||||
8789027980293848952uL, 5914590821894013971uL, 5201360692628199003uL, 1438508405363181993uL, 1047132165489660606uL, 5627682402975382898uL, 14753809747772696347uL, 1966322907280535614uL, 2694302999865518549uL, 2361664381868374374uL,
|
||||
13457635568901744811uL, 17504877959453114096uL, 9317025438026129907uL, 10808279102775697669uL, 6673472819996841645uL, 10887564197671041257uL, 13657089091486917108uL, 4917937056650714377uL, 17110791576323341323uL, 8472979738121466922uL,
|
||||
12991487546715896341uL, 10838903498911111839uL, 17212902440124499857uL, 3621785006072287929uL, 12125479410148983668uL, 17921053425751121547uL, 2600818822502173603uL, 18095853622957810961uL, 5457179844010077633uL, 104674322205155958uL,
|
||||
2459119713154539658uL, 10359563843775427405uL, 16481219104186197994uL, 8162692825194907375uL, 2847061296053530681uL, 17007385453270867581uL, 2429042753721621264uL, 15845690715266440311uL, 11504223637356675454uL, 14939902389728255105uL,
|
||||
15596543964592056301uL, 4291817720210491736uL, 4250406047929019182uL, 16835609371473809102uL, 6848231166907919671uL, 5722504929196957444uL, 13163410864325338105uL, 10169775613993200289uL, 14511240905997678504uL, 16428453455105502901uL,
|
||||
804576823300162061uL, 16952328422295033634uL, 10704308825032065907uL, 9209752147493311569uL, 11915204881515227728uL, 630314289831180695uL, 5090994841956713701uL, 15144339993900648342uL, 6320413364043601056uL, 4136912626218684596uL,
|
||||
3688671278293774543uL, 16325117494106688707uL, 7111516025665441606uL, 12019670279683559882uL, 4747430357904739770uL, 8503693248481660848uL
|
||||
},
|
||||
new ulong[256]
|
||||
{
|
||||
5022191610516858060uL, 12645839371960098056uL, 325196729119310435uL, 10544111738277527250uL, 17171723943877278631uL, 1619663718359036237uL, 18091587880400184708uL, 5335828035754758151uL, 11379178129143138841uL, 14648217640238887722uL,
|
||||
13086832364598786016uL, 15914535959731104950uL, 1287844858498292800uL, 16375051820953423571uL, 11583759697334954435uL, 550964732710513933uL, 8585995564513096669uL, 15686472308550713348uL, 13325075562694951572uL, 17630740042449523023uL,
|
||||
8916962000159598712uL, 14192583705586485217uL, 8560921352511315212uL, 7426955371667046732uL, 7096434795747339774uL, 2543027200294554449uL, 10419956338547081069uL, 5721517685081291957uL, 1937338776563641064uL, 13736071204485071176uL,
|
||||
17106932809158825161uL, 4899378514713126672uL, 14773093419524387062uL, 16698373717390806192uL, 3710095511616993728uL, 7340570904524980467uL, 5918098101825092432uL, 10804520625326298079uL, 9730090089577636081uL, 4697601972911171247uL,
|
||||
10480451310123618748uL, 5151346661287437683uL, 3331340938598661669uL, 9395203941325327427uL, 11242079635202581704uL, 2915854855682031097uL, 1492126639482712306uL, 6290138385502410722uL, 9851336768255988794uL, 1856873279258002822uL,
|
||||
5831708560246045423uL, 9075623880903535524uL, 8815370023405405865uL, 13167394464051894414uL, 4378109956818586891uL, 15006898764834764563uL, 17307241128934970156uL, 2668061343609997453uL, 15557224681013713438uL, 6825682518352077045uL,
|
||||
9524557205897875359uL, 8172884461239939073uL, 12192217863250075348uL, 4603827798664618597uL, 2867088101655710002uL, 8332998285759836606uL, 10671362497273609486uL, 4672530790940461182uL, 1134559637999613131uL, 3897488771451098482uL,
|
||||
10309743511802411319uL, 17673793229178945438uL, 16718005676701005947uL, 7221495326637043234uL, 16597347416266760801uL, 9272158342823316988uL, 7909827430729881909uL, 16002662719275707657uL, 14283453708927338078uL, 10869263363796925617uL,
|
||||
16345475348111384578uL, 137665338910158545uL, 12515539920715504823uL, 10988984776972674731uL, 6746265954835287963uL, 18257106040948926040uL, 17421816711713963517uL, 16919288509122574788uL, 17268808778493482358uL, 5838760703968564286uL,
|
||||
14031617523076498493uL, 780392312595241081uL, 18336540041995274550uL, 12842206973407828717uL, 13656722531824102950uL, 7015947325939974800uL, 3645098545556231953uL, 17884924832500353770uL, 17512690432282197058uL, 2066784160966486324uL,
|
||||
13412572121352667947uL, 2661572689932379740uL, 1033530071105264154uL, 12957343035395093564uL, 13868125990049039746uL, 3121291101747188375uL, 6662680657495023946uL, 4471231211228269748uL, 15424627025727239375uL, 12580275654379647961uL,
|
||||
4219404094166535895uL, 4762278602948970945uL, 9478790587773903506uL, 9898893830113671915uL, 14973264685418819913uL, 453876631214605276uL, 4407685011702703066uL, 6616899736578362439uL, 13003248198425336113uL, 12419015558860141158uL,
|
||||
7990341289637279323uL, 14442713494739508292uL, 11215801851269958085uL, 13332124370822523973uL, 1373724075619900927uL, 13783625232014225305uL, 15359939653945809825uL, 12751808085835111250uL, 6083572248920684684uL, 3484333688484746926uL,
|
||||
14521793786758034069uL, 11937786166553331057uL, 9139255992929895626uL, 10222251748408277128uL, 12255784141711061434uL, 2189202321390233739uL, 716843780901418775uL, 8359149623152811187uL, 2415494092048157422uL, 5243176795453837752uL,
|
||||
18210112488466909321uL, 4154687863979303353uL, 2272222198031926874uL, 8690072078618429206uL, 202427615156584895uL, 9639695198538801486uL, 18415623364178962407uL, 8942462418363155829uL, 907753262429150117uL, 11810680268281218733uL,
|
||||
7665181140788048952uL, 10898276329415234144uL, 3239326427400699802uL, 6868174095610514980uL, 3808219771792118989uL, 7543278091629671815uL, 9168270020997671451uL, 12392885120222240619uL, 968811775037617524uL, 16140326090467902424uL,
|
||||
584245825585813958uL, 15816256665709806011uL, 13531648566339513850uL, 8750568181363911111uL, 1698743779072106396uL, 0uL, 16943798148194031381uL, 8236472591980224367uL, 13209882775544247903uL, 4035151075898375075uL,
|
||||
10302693318479402982uL, 16855667680011982506uL, 1948891778265760825uL, 9719098429884157472uL, 11054545481701918842uL, 18085100094794517333uL, 390196158411648178uL, 6501762612143760022uL, 2496032298569901440uL, 6037175610368660865uL,
|
||||
12762796728381896067uL, 14204135840323823920uL, 16148186350413554109uL, 17041934512146922008uL, 4925668384127994397uL, 12167143351085101061uL, 6410254435445760809uL, 15330361267764327792uL, 14853624750388125592uL, 6421246412478107128uL,
|
||||
10056755301905365844uL, 17754265602204553456uL, 15589384456651501269uL, 3832728561082858012uL, 1367237356757087022uL, 15171532294165509804uL, 5272189459801538409uL, 3250881896629883211uL, 8001331881476413578uL, 6968391399550921793uL,
|
||||
15232592138832550013uL, 809969847888836264uL, 11442741800557897079uL, 11677520222457276540uL, 16472678002634826718uL, 11836194988174371744uL, 15751256438176362346uL, 14766608101443821095uL, 3078237133952334918uL, 11467814949005020070uL,
|
||||
13951147765685021523uL, 12061945554227725518uL, 3445914570843754740uL, 6242581091097786675uL, 16533735384072260879uL, 1539119056502398499uL, 7794692769390540772uL, 1168206872894059153uL, 15939048079214002791uL, 226938317788999534uL,
|
||||
7419906245093191581uL, 10103172840323946073uL, 3581420404919564415uL, 10645700449263505411uL, 7585766634561542998uL, 2998877762491110184uL, 7174951347083690799uL, 8107322624236560080uL, 13578204632486592759uL, 5494625981129708507uL,
|
||||
8496251452686250594uL, 5596216022932782346uL, 5661024595188978276uL, 2747447103066187747uL, 16280780971239378796uL, 15107926451017931202uL, 14398026278718810255uL, 9978235489092097413uL, 5085786205181774754uL, 4053661314365738856uL,
|
||||
2109836211124176869uL, 2336412667751326783uL, 11612775692986304274uL, 9314648022329008941uL, 17501136362727821971uL, 1742301027778505559uL, 14601226005391810043uL, 7748764524654516969uL, 18004566148294681659uL, 5468987013722291926uL,
|
||||
6162091280534394461uL, 4280460676255686662uL, 12001449201751239199uL, 17837288741426265633uL, 14074668225098984172uL, 11119279424363751188uL
|
||||
},
|
||||
new ulong[256]
|
||||
{
|
||||
412778415529865760uL, 3577342882794069583uL, 12805512713741006036uL, 10086389182405830274uL, 9631348414619490491uL, 11029226397073373641uL, 11627792458048644653uL, 8540370589362648094uL, 17925746536371200188uL, 13719614496949379764uL,
|
||||
7380585705851070183uL, 5532990722829248072uL, 10754888447158766146uL, 2363770411641709807uL, 4799219136276863089uL, 886827555711267723uL, 14761170299289685203uL, 10870602893012709289uL, 14053970170398186163uL, 15159452414945845267uL,
|
||||
152494743391849906uL, 14797380007077078154uL, 12067788661428416998uL, 3618765265895209892uL, 16730148953297482309uL, 6638666397703976113uL, 6746862217775881448uL, 12434579095834639871uL, 6325409020385589416uL, 11881705736862929933uL,
|
||||
4058193356686090212uL, 7086287341885701278uL, 15674826541200387082uL, 10483145580681646139uL, 11728250915792503750uL, 16457218618247725518uL, 17804566359647483612uL, 9778627006082503945uL, 12613833228843374612uL, 12973791078126503668uL,
|
||||
3891946276334412253uL, 15267727468379129930uL, 17962016790450440421uL, 8437586805018431989uL, 10621274027794111881uL, 11432405351048939099uL, 5716202677831336867uL, 3243582143937888061uL, 15866832917474188842uL, 16875173606078234615uL,
|
||||
2399609570378190006uL, 7345426154655236876uL, 7619693495944769671uL, 15822815208912544184uL, 15130995325890332152uL, 9371659578628761385uL, 7194324827586368711uL, 4309013456660281871uL, 10250322826443576482uL, 4166240605864818621uL,
|
||||
1366177816882650955uL, 12337542112347144813uL, 6217414342487101681uL, 7783606731388437159uL, 17120176822620799077uL, 9037712741102696455uL, 17012341578268600380uL, 16118235504218274753uL, 8304362858347251262uL, 8707177795482651175uL,
|
||||
15023151349731995041uL, 13385369152941776166uL, 16304327354866472453uL, 10358449395342638331uL, 18075424330969541902uL, 11764513330537491359uL, 11174112167783249019uL, 11138113584220445730uL, 1945973140213898976uL, 4200834197375652438uL,
|
||||
5435457027409418714uL, 7756135292223372597uL, 16717045777202619429uL, 2508515451320396125uL, 9523284449426682082uL, 14317999436018362515uL, 609168629503044082uL, 3755788431048666223uL, 17152592151573603726uL, 5399380291345002883uL,
|
||||
12301351165578275380uL, 12189559766827372511uL, 8884253657276313548uL, 7648167075477099884uL, 1809525021741863762uL, 6185017703168619802uL, 14510683649402109683uL, 2064551487375270258uL, 16010179378360767384uL, 3469367101608228374uL,
|
||||
1536322983539794137uL, 5796100959046534970uL, 1773386847580617483uL, 108346540153546841uL, 9001722862285623390uL, 2544785687349641476uL, 17260840743582043607uL, 551619354788593554uL, 16565125331131263383uL, 6486896028513362810uL,
|
||||
13119530067680070470uL, 717443701121057195uL, 2214371934970162368uL, 13227357483453784863uL, 1140410460104840800uL, 7488913346602372798uL, 13429536041485875405uL, 16412374620625092188uL, 994812197283306450uL, 10114437580603988240uL,
|
||||
2804228341285155620uL, 260410206251574763uL, 11468694089796595202uL, 12153782305157883782uL, 4835367340339408936uL, 14935941453496953144uL, 6348897592219414216uL, 13580632830920879878uL, 10447068863337265250uL, 2250650893928301721uL,
|
||||
7511575676904462558uL, 10993078211198701968uL, 15566911097060688979uL, 443413779826989003uL, 16983149403301320622uL, 16608725716676480124uL, 1500526641193339008uL, 8152292870049500044uL, 9978535451240877787uL, 11591943528381025908uL,
|
||||
12470629360879408550uL, 858245894210178073uL, 10222432276826665289uL, 13827511182212795117uL, 15446122921225714282uL, 8743440194190385790uL, 1218336215312585465uL, 1032276353674575417uL, 14900145093364744545uL, 18402470457342123822uL,
|
||||
10906820163225880560uL, 5903954706119241571uL, 3395223664118723215uL, 5940852870679710344uL, 12577914836476031053uL, 4685830293981560218uL, 12946605235894991206uL, 9228745979626367643uL, 11917827469888011348uL, 17379906352690864407uL,
|
||||
9183300283681142197uL, 4649831692234020291uL, 9147178532201324012uL, 15296022985070163928uL, 17486629686828287228uL, 0uL, 6898510060154343770uL, 1643589765241144626uL, 12697544478944746637uL, 1402114711967872786uL,
|
||||
13537723148088938644uL, 9937131744855075632uL, 4353588900056941981uL, 14172271166703691041uL, 5292673456375059560uL, 14626957485788666648uL, 15714468687486372321uL, 9828864528591782761uL, 3999781539141355908uL, 11292166047742839785uL,
|
||||
15554107579106054707uL, 12031798801067137471uL, 11328023846638773168uL, 6049120102845506257uL, 7933416458737094421uL, 4461908978498334148uL, 6790446112744143107uL, 3726873057198478333uL, 7237529453753559893uL, 3864037041512891446uL,
|
||||
7046626506133690741uL, 304722305440127609uL, 18266442068824101532uL, 14208550143986027896uL, 2934657069911674141uL, 6076891152586415427uL, 14663026374551417665uL, 4953135073593642938uL, 5569207977274658321uL, 4501008218251986991uL,
|
||||
4608914949056012406uL, 14017832012144685802uL, 4989423796032989155uL, 10719102116777386523uL, 3207522108247185252uL, 17522399594662456485uL, 3108845752482162934uL, 12838487398799446335uL, 5256746322603637809uL, 3359313093287303894uL,
|
||||
1679799455245938027uL, 5680416363222969338uL, 10585346912750056912uL, 5089304188877242888uL, 5125161971465923153uL, 2663698829192085142uL, 17343705367582804302uL, 18366341168314316663uL, 2840208181611518845uL, 13688960456037058399uL,
|
||||
6456820608799639185uL, 7891434163331525374uL, 8401668394735843756uL, 16166056177409219511uL, 3072644785963581615uL, 17657281445989989230uL, 9479582578768039792uL, 13876877822288985944uL, 8268585413250313831uL, 1254405120516291232uL,
|
||||
1909966976157497017uL, 8848404743649085333uL, 14353865065657041098uL, 9670431168224853328uL, 17768506339595050629uL, 16838256760641149468uL, 8116101939860513749uL, 750401899863958592uL, 13277331648651621759uL, 6938439418119057708uL,
|
||||
6595232530173053731uL, 16274235453266392046uL, 2970426959157404996uL, 14474746770758882986uL, 13082049433730969261uL, 9337082464844055234uL, 15404157107807690625uL, 18230462244674452165uL, 8576420872327912519uL, 2100417098697099563uL,
|
||||
18111263507761251671uL, 15975038508208797299uL, 2699828134389257935uL, 8041674830518265676uL, 13912883970442876673uL, 17621370890793685815uL
|
||||
},
|
||||
new ulong[256]
|
||||
{
|
||||
4535860555263248921uL, 16852860281346875951uL, 6140263643322089338uL, 11478926500824812339uL, 9378015351203239756uL, 13327564710645084082uL, 14720227639147585363uL, 3976828915743059002uL, 10848963853955034384uL, 1674533312481288529uL,
|
||||
12560205794591624211uL, 18251760262641326195uL, 1971238590622152549uL, 3457832774275448914uL, 16150883333172724748uL, 11794428727689681111uL, 4727861667757458726uL, 18086103234836705689uL, 258683541723454221uL, 14234423747971299696uL,
|
||||
13746687986412618920uL, 2233564259985426290uL, 1378062126584976310uL, 595850907021173971uL, 1148729542089166137uL, 7220711707371485274uL, 4275768676387371534uL, 3496324401055548880uL, 5165544922527804988uL, 17490393461649265994uL,
|
||||
8412095690608439521uL, 14978908882929042526uL, 16577882496662810390uL, 8847930418030264104uL, 3309372870217980335uL, 12420682712621503982uL, 15313638727721349947uL, 4387469920445666276uL, 15069308889790759724uL, 7765336488733668707uL,
|
||||
7626271911434349726uL, 11162557623114971940uL, 14550225336477740868uL, 15462274553512913606uL, 14126703745409497984uL, 4089712366057758979uL, 2084822880951770767uL, 15217945823675505361uL, 15628305894032057615uL, 12769693467676363153uL,
|
||||
8115270375799669254uL, 5758785072471788271uL, 17025131558859428408uL, 6401431119593581502uL, 2607396063788253068uL, 149165799264492029uL, 10429296302893549066uL, 10743412135794079261uL, 11655258597668356394uL, 3161051439931945653uL,
|
||||
2862129545546507393uL, 12732210800733670241uL, 1786865009825524840uL, 15183877174701053985uL, 3531814185980970784uL, 1489042636343605852uL, 7953372014297400692uL, 4127379132466308083uL, 703148615521134115uL, 3051392466055327813uL,
|
||||
8884721462095101400uL, 10883429997862481888uL, 8288941250235652363uL, 18364623810490598270uL, 2902931453887900088uL, 8254758264932555771uL, 446716860198103834uL, 6435790520947517774uL, 13467158152785180239uL, 14590483660463305801uL,
|
||||
9043176952977856194uL, 5945702658036389520uL, 5618980515518141202uL, 10464882797601703162uL, 15944691810401457432uL, 4424111993825693972uL, 13996955283450564762uL, 15498010045204162614uL, 15034711375462777308uL, 2457938976092230806uL,
|
||||
17280995377108044085uL, 1042563110803492809uL, 14698967823614015161uL, 1000057432295396548uL, 298081034413880039uL, 17972098505603721876uL, 9182311907627011903uL, 4237995257073580286uL, 7360269973856297383uL, 13151329901121790075uL,
|
||||
12073241782278564400uL, 14383131042028101773uL, 6575665438039683251uL, 6873491385755763284uL, 5461089107914913800uL, 14868969018190677678uL, 10359842278252856200uL, 9238174518821588657uL, 17527071737039935418uL, 13502357048437945535uL,
|
||||
15348847553065546187uL, 11339121943878505166uL, 9517911241040346198uL, 9971396702494946207uL, 4759102407226695211uL, 17378647008906169927uL, 8551269127753525532uL, 3200854107087625055uL, 18216411296800512643uL, 2268055074172700034uL,
|
||||
17342145754611272887uL, 16259542889635186428uL, 7467557820838912855uL, 5842407176390331805uL, 13781293231417820760uL, 11545326463606686682uL, 406460662087397399uL, 12248428481276306937uL, 2713878548564622716uL, 15813794323767901698uL,
|
||||
12909252825081827436uL, 16687682160775540198uL, 13363292471131286850uL, 16093363920219344101uL, 17173522193701129157uL, 1340149631943889222uL, 17937642222676617316uL, 13187698676877812363uL, 13848249080340613479uL, 10604652161736989959uL,
|
||||
8063408691889325956uL, 2565552841162102374uL, 4619087852284151766uL, 5214791045043151621uL, 11825258692200411453uL, 8447401294454977041uL, 11060374817020715049uL, 2118998135578172543uL, 18400220166708232590uL, 1638138058256147361uL,
|
||||
11933752785043076045uL, 11022751975238574809uL, 7923814141646626425uL, 8745197289204327461uL, 10251172860281438584uL, 110046607829271280uL, 17001249825241725906uL, 13607620101989539157uL, 12527281127159060254uL, 852275931467612126uL,
|
||||
12280242513132584692uL, 6838009262779170980uL, 17658513533341858976uL, 1935925255570044309uL, 16894801472302283042uL, 0uL, 9624367324648619686uL, 5055648419791580364uL, 744521925918424366uL, 8708792173461317333uL,
|
||||
3012835619118082888uL, 2417128113004220315uL, 1525826018450700460uL, 9485585257278707132uL, 14103543837016167018uL, 11442415316829571523uL, 555623154201897450uL, 9144795202799799759uL, 3942477176883605194uL, 9657855435820246443uL,
|
||||
18120314326393467753uL, 5511376580148613602uL, 15664667007830861823uL, 2755821882842654321uL, 7814304129864883337uL, 5354596692910111480uL, 15776976912903093490uL, 6280103384783087239uL, 1191443428809820347uL, 9831487700257630818uL,
|
||||
3349066620751495842uL, 7030425627006208077uL, 12141104268537423625uL, 15906742984900188136uL, 17132709196148330696uL, 11964432129338157248uL, 13954451705047518103uL, 4572398174778067177uL, 11684814352765786663uL, 12387952654176517124uL,
|
||||
17620705939241991760uL, 6698133237560285529uL, 6924249334748056253uL, 4915877947555788081uL, 10111296835088767109uL, 13048598907028568950uL, 893432504920462900uL, 13011771634646415750uL, 11302435937273876542uL, 3644679859973545005uL,
|
||||
1822496103478537880uL, 4867631031866531035uL, 11200357486546532820uL, 9345637772528684097uL, 16055873590790557205uL, 5651355959728424991uL, 6102500154237255050uL, 5321106438415311349uL, 12666416081784098531uL, 17769131758322608045uL,
|
||||
6541340121823556163uL, 10219929968899119733uL, 9941277503389493394uL, 14829851944308301219uL, 5982354661116236896uL, 7656949129855104915uL, 6733579076392590249uL, 16299238792081284593uL, 6242444349043369079uL, 14275799167331476093uL,
|
||||
16539327809960162331uL, 10709193381743359213uL, 7063352394543305536uL, 7169984984404332976uL, 10081152420505776495uL, 5805861825662078829uL, 16746518581295898847uL, 9005272120822338610uL, 14441423414742904244uL, 8149771120223764726uL,
|
||||
16429564429454849771uL, 10569310857845530615uL, 12871313860553036444uL, 2309691269046898027uL, 3794159109699761975uL, 16407864263942807297uL, 5025527060452063169uL, 17806764530333181277uL, 7517355687739125358uL, 7328458050963454634uL,
|
||||
8586890291714583532uL, 9764207066100180827uL, 1228969994608986699uL, 3680135560314805981uL, 13641698681201336229uL, 3828474564935022023uL
|
||||
},
|
||||
new ulong[256]
|
||||
{
|
||||
9993673838465935981uL, 4884127456122942266uL, 633234397777501925uL, 4175331866391974078uL, 13960862214643959730uL, 3179702086296496554uL, 16933906489121384602uL, 10694170786544668381uL, 2821567796802171918uL, 10017225945983459410uL,
|
||||
8620367719189969058uL, 11912340740684202118uL, 2483193514877514189uL, 15820547210744392958uL, 6709821147687032714uL, 1033155461149792359uL, 17176581185527344473uL, 12676916669343913757uL, 7895548116537857006uL, 17715094920495729706uL,
|
||||
17733400074663874411uL, 10798980099858302178uL, 17017586219309622311uL, 14869918229733283306uL, 14186578078356341361uL, 5087312367917758201uL, 4403136284925796162uL, 11445060531346954566uL, 3775805186400799640uL, 7039684027147830007uL,
|
||||
14348961028615061808uL, 9697319919564979060uL, 9738807224246382923uL, 15223411982051930651uL, 7393281011622612554uL, 14606960238789696022uL, 11882147622572427961uL, 4010248068099147993uL, 1391157335655481238uL, 9401574542884107400uL,
|
||||
4570854599768479292uL, 10257649927482729873uL, 6677411409753660853uL, 1869614486838700045uL, 2692552123250949488uL, 5803321545042218156uL, 2939237684151739990uL, 12563222234819403042uL, 979419644422445862uL, 3673082354135452954uL,
|
||||
11533447497148368197uL, 18030958354471640690uL, 17612545135863809557uL, 8160101394646269472uL, 8665997893524695802uL, 13625616718215733940uL, 18235386795261924047uL, 5384800866856167392uL, 12916723256358730451uL, 13592733055320369291uL,
|
||||
1572125733959825684uL, 16319952048648813632uL, 5756880660441440803uL, 9141459606454807672uL, 5643134515567552540uL, 16615690806985356220uL, 3878345071173861799uL, 9227030292403715574uL, 2223083610095396016uL, 7793025783231257041uL,
|
||||
270525564056519489uL, 17847006580419200340uL, 14816163592450856619uL, 14466615231819486056uL, 15073980746734173029uL, 2096675571659106289uL, 15724638447412750017uL, 11654178806006959994uL, 10463964225571785502uL, 3546709370140069467uL,
|
||||
15706368347685578112uL, 177299642257213822uL, 5128824965654363334uL, 3284371762775499669uL, 13419641178229583369uL, 16654934045169170819uL, 18403114047913597873uL, 14517143817528858967uL, 14108395695510474444uL, 11707930154007137339uL,
|
||||
11096530083400914427uL, 1469770529583346475uL, 16266162354777931521uL, 8788550027033796805uL, 7435101501630170229uL, 14015179664977724659uL, 7273261710249789236uL, 17122228403727216152uL, 18126471264669209677uL, 4054715969654905473uL,
|
||||
7599903567200476178uL, 5246485543787097758uL, 2066061333143563726uL, 8899911909190592955uL, 11318703078624401927uL, 6203347905963379246uL, 13279357838919968631uL, 8982737327710905606uL, 12768987285517661101uL, 4733860583378205252uL,
|
||||
8385890890472733667uL, 9576385652165374474uL, 1983784429268132211uL, 1144615724587504216uL, 9497500870535659191uL, 874653248460230937uL, 8806272569836118916uL, 13123279255654448912uL, 8490507753801150940uL, 4996983704035276216uL,
|
||||
15899414662248931395uL, 10203863540057188048uL, 3101674511553930519uL, 8063548039483480720uL, 2782314667368316465uL, 7188904195392064393uL, 13234879149618951471uL, 9015613289737121593uL, 12161612559689161632uL, 6918945025995344072uL,
|
||||
10371370779234316206uL, 6314684983379722257uL, 18205211228616546544uL, 516733887222336701uL, 5295035016025023649uL, 4372970618206377341uL, 1367579971541251497uL, 16771488207379590107uL, 4788193436127426821uL, 10413312453672812833uL,
|
||||
16525909700027724029uL, 8286510523341552993uL, 4528946180991933443uL, 17331684625243261417uL, 354332099228667900uL, 1703685653761847402uL, 16413616708890474111uL, 17892572632091416332uL, 1749306493112033842uL, 6593587578816598280uL,
|
||||
15307631993767476902uL, 3696774096474081061uL, 6359145787360465481uL, 13751446413401596405uL, 7551609152712119853uL, 15025544492090470746uL, 18361178145650889102uL, 5408360666650553823uL, 1887903149406137164uL, 11803390319907948036uL,
|
||||
1193308391354416343uL, 12323998817483741409uL, 7714012032021747052uL, 17506448615360610455uL, 3338705706857455828uL, 0uL, 14628435370100609065uL, 16493078850282879682uL, 8307846011238545246uL, 7949845912698622127uL,
|
||||
123000737600621119uL, 14981351001126100949uL, 3896669045897085670uL, 1241734746156300008uL, 3450192318869875435uL, 16822271919490900452uL, 773588076271081371uL, 13000385682190022254uL, 4966387029739569031uL, 12002158269635560391uL,
|
||||
9180589562619618887uL, 10928066111586602396uL, 15930056384200567420uL, 14219030733708445774uL, 9855367461831697171uL, 5589364474795928413uL, 12718291570760726930uL, 13105010246454705233uL, 9347225068603062217uL, 12895380067559026924uL,
|
||||
795073098915667364uL, 17380094451920307158uL, 12508908074841628259uL, 7690267545386164051uL, 2659693781377578831uL, 13401935256959085896uL, 10589758866316740703uL, 6500344023943830327uL, 16056445859796592957uL, 13837888969188904333uL,
|
||||
13513288218419651638uL, 1589851584549665365uL, 2429422383846896268uL, 6482023338771290230uL, 15410014681647150233uL, 6185590308720085359uL, 12209899281950724511uL, 9606974634150672437uL, 6080806279852835664uL, 2576885667214146546uL,
|
||||
11484734779036570489uL, 6001208834408615917uL, 6836195239104500939uL, 12406411034606736476uL, 15541565663606373863uL, 3080356643708727080uL, 15586050454049992639uL, 2306958247692105907uL, 12043971067315669496uL, 477155333442143874uL,
|
||||
14711407087855869076uL, 386794645880882627uL, 7093418736453091766uL, 4288595764497750464uL, 15199807134400952356uL, 5979776620583929298uL, 14309409966946880271uL, 16143708109906736446uL, 7303480121366170891uL, 10973644831137980356uL,
|
||||
16912616113304036005uL, 11114834129878537914uL, 11286268056177528888uL, 5486956530453307746uL, 16097845240139637506uL, 13790601654062869450uL, 10611216364554256992uL, 683790475565323482uL, 10101463287957875951uL, 8109430964352234527uL,
|
||||
4193092754259694591uL, 4613640514157211771uL, 6875861785975561972uL, 2264473090495966863uL, 18013216012281093427uL, 3498327026982732900uL, 9903891640980875564uL, 15427721694518818776uL, 17288057906222606182uL, 10816721333284587427uL,
|
||||
12300279623953421022uL, 8508793109654811293uL, 5853965616021964435uL, 17530150257591650984uL, 11208102969231252613uL, 2990031287613762665uL
|
||||
},
|
||||
new ulong[256]
|
||||
{
|
||||
9094991057681989827uL, 8606138803235823195uL, 16160543087529014701uL, 9722527943682365778uL, 16797595215276895029uL, 4026406244121087995uL, 10810880735842556538uL, 793466831469952157uL, 17570873574801040652uL, 7069806061322532341uL,
|
||||
9025437343642800970uL, 7902240744518357090uL, 11483956163069641954uL, 17042883494617269171uL, 169507756355412485uL, 12159611706920405785uL, 18050581113201408916uL, 13094669269567229859uL, 8708198706664012748uL, 16371399438833100324uL,
|
||||
14361924315882092926uL, 1669125631761648043uL, 14039613357159666168uL, 6740073072435942682uL, 9627137974267120347uL, 2010954567078870965uL, 17744533894276238730uL, 15208954621100286812uL, 734067863229058321uL, 16730891229222345401uL,
|
||||
11666396599453668737uL, 17212276558031167926uL, 17506990798142313600uL, 919214179616323102uL, 13610264944790049083uL, 3253262042600145346uL, 8178958160323126612uL, 3337947751052939851uL, 18012048573685573661uL, 11417239120312989038uL,
|
||||
14850353257827313638uL, 1052577896389186587uL, 2193586592470914867uL, 2442179127876909020uL, 14667795724615946080uL, 10275106697555981894uL, 5137708932055784227uL, 12218975353350290069uL, 10142868812109927491uL, 4815958689639822245uL,
|
||||
84753878177706380uL, 6315843737766598667uL, 18382000460611982098uL, 3871579785502944766uL, 14543332760762117477uL, 5793075969118851720uL, 249718177605522313uL, 10016556418199002816uL, 17931853270716930449uL, 5498396982908774334uL,
|
||||
12758117762690160297uL, 7667703386526505697uL, 16683173451180408622uL, 9308406252338238417uL, 18135310527241439768uL, 1929022448056995385uL, 1586665506641377319uL, 11971724948115332866uL, 8445678447034858590uL, 7274058453835599610uL,
|
||||
2629305166521655130uL, 15808997092930047048uL, 8787833086900898368uL, 1545819354008644526uL, 3789645467455986802uL, 5856993792710681348uL, 17343191981176845957uL, 2091361543251510458uL, 7459518732372467059uL, 7397325080452181247uL,
|
||||
15335405622202837471uL, 4059487177496226412uL, 559362848516098691uL, 3155811880282733261uL, 339015512710764810uL, 499436355210984207uL, 4260721118560188901uL, 673503137787469464uL, 15081211333024874841uL, 4141949501641595872uL,
|
||||
9781889391086627038uL, 12476916589205824415uL, 5626135598191838651uL, 15420137235268491347uL, 11586150856392483853uL, 14798864416891614319uL, 9563233069935360855uL, 16068176052423353550uL, 5444143179324534077uL, 11152674838723308644uL,
|
||||
609631631123197716uL, 12923016366159787180uL, 5576337977799677490uL, 17125332349745738303uL, 17828665414509968390uL, 14295222528848431346uL, 4387173184941765478uL, 13364476147137460669uL, 13874622463430112253uL, 5708620050009289783uL,
|
||||
6430542613299891216uL, 15458737944500718554uL, 1851664366124113328uL, 13012174097513791023uL, 9392599482526842968uL, 10442066843459281269uL, 17402610465748322057uL, 10690912919127767167uL, 4978440652618840358uL, 4581695294717042927uL,
|
||||
13282578800170846257uL, 3091344129077791553uL, 7147744857192531065uL, 4652093626960253344uL, 17290252874733146170uL, 15016728463536386261uL, 9833286126441041225uL, 11912919544491543691uL, 16242464486312756257uL, 17589663661478784911uL,
|
||||
1346746777927262509uL, 15729327665759993284uL, 2259738658050909887uL, 6111753265489546114uL, 12645228008055390618uL, 16891355708455647420uL, 16563324312999238955uL, 12860835633502684448uL, 7729369582102031213uL, 8912221009216268357uL,
|
||||
4519477316101755235uL, 1281193087194051236uL, 15149005862685217488uL, 10355350241595738058uL, 8118974354974954712uL, 9897718555834973381uL, 8521442237103337431uL, 8066035438451585639uL, 4453855455643222762uL, 5377403871458974897uL,
|
||||
6345848246193028508uL, 6845086483143640723uL, 7988624098924168171uL, 8365446172989525458uL, 1467823520972380706uL, 2935396374752471364uL, 2813067799104965843uL, 10892780281834253302uL, 403485462937118854uL, 2688701935736925910uL,
|
||||
15963727550304450375uL, 14201530205386742651uL, 3468874151188153720uL, 13250621696684830118uL, 1132260792577222039uL, 0uL, 3535028415789053172uL, 2491459977799754837uL, 1003369614229768082uL, 6675627174024062102uL,
|
||||
2029743588748113206uL, 4729507165508558892uL, 3637180897245407101uL, 13952596581111186033uL, 1413426849607831713uL, 12561037251630870550uL, 15570063509623791553uL, 12397269289706770963uL, 2575613213387593177uL, 5320806183970131768uL,
|
||||
11314453079775012583uL, 3422699430205023175uL, 11852957454497512711uL, 11074756040358150125uL, 5071567999032830639uL, 16127596736020452674uL, 15899842574624294603uL, 12691402918954395429uL, 13406940540233951796uL, 16497147783287368871uL,
|
||||
14139300956777540343uL, 10637081362510967548uL, 10227584894573028815uL, 3173053820371464270uL, 15538935446490790486uL, 2362498430710285904uL, 4897844766612488745uL, 6236211556551125383uL, 9224217694939325021uL, 17669330889627426307uL,
|
||||
1774266358176803900uL, 10768348173029132787uL, 13484373595114429368uL, 8283899003267266269uL, 4916772258018216106uL, 16294021496973776808uL, 18249652692721135895uL, 14601621393924980460uL, 18317519790144905886uL, 9472244583004484052uL,
|
||||
14932272457585972842uL, 12314433492482058524uL, 2749198491462122847uL, 10503721769042972921uL, 8966051432100897478uL, 9158911080295248207uL, 14481701886997601513uL, 12036159576530677390uL, 6195919557778536974uL, 5258610333024763572uL,
|
||||
7340795562680270710uL, 7820356866570772974uL, 14721488674053178851uL, 13743694907000058686uL, 1218977307603845928uL, 13172660635703827498uL, 13676381963436941495uL, 5926479337025089677uL, 10996792780356243041uL, 11235172209801846248uL,
|
||||
9956596527230578508uL, 11798704853650126724uL, 16953587156089932080uL, 14122060013263036532uL, 11252270148092827499uL, 7508364738339027172uL, 6905068089466205983uL, 18189706133331673243uL, 3949006037152890487uL, 2995320669031979208uL,
|
||||
11713986572161402376uL, 5985863049541370113uL, 4182723086503020649uL, 7574503472341076328uL, 8348347100700559185uL, 8828052517901670857uL, 6506238233651847065uL, 6937453620375099376uL, 16621540378390793890uL, 3698801050773903089uL,
|
||||
15654197228883127885uL, 7019935873167451772uL, 10570962144843170672uL, 12378340595835246736uL, 13805347633558651570uL, 6586468308675751445uL
|
||||
},
|
||||
new ulong[256]
|
||||
{
|
||||
15001986890517004262uL, 1637721477308921125uL, 12149495623811231944uL, 7646921253694161755uL, 7930897700415732235uL, 7354091399752226219uL, 8517004666874317814uL, 5453187778286554101uL, 17402767330240624456uL, 14251910686351372799uL,
|
||||
10737788899373396171uL, 9883539568181426278uL, 12734457949266690357uL, 11623707008269186684uL, 10170823345874272566uL, 15471862682949014686uL, 3965582442916511115uL, 818990539008627868uL, 6511022660614307004uL, 17126666484504068069uL,
|
||||
15184024750296067534uL, 6797246517703968236uL, 2154964243676750265uL, 12492451583515533452uL, 3398770582681996406uL, 6305239209379988312uL, 4529647259392179007uL, 14544757854385923855uL, 9493043882612360686uL, 11962608485028754448uL,
|
||||
1169952615461543517uL, 3200289132027606858uL, 4147956921301236051uL, 708224122457687732uL, 14832107397699362399uL, 17986746842616076520uL, 11299623869485987455uL, 13594198486351288261uL, 8231768351619019430uL, 8694883466081947438uL,
|
||||
1455760652066973453uL, 9579750024852670338uL, 11015579459201929007uL, 17314613109171068508uL, 15811118054803696506uL, 7243836256093423491uL, 3660620939660078543uL, 2208053939432577669uL, 16834810824707884725uL, 18271848992774824376uL,
|
||||
14417021283697659419uL, 3377712478417560930uL, 17894792228341543420uL, 16945073801847805085uL, 6217894297849621068uL, 7825436358742779939uL, 4987043392780078893uL, 12382858497269484532uL, 13415820639865306301uL, 8746199649574856250uL,
|
||||
869662533239166704uL, 14650457721364100391uL, 16925141562858405257uL, 2911244210510417434uL, 18382312974373876624uL, 11498597901617990979uL, 10828667572279970807uL, 5928147536793457436uL, 11212941572902532115uL, 5738424067781505701uL,
|
||||
4545920254677684779uL, 14357837190168765399uL, 10540746283984138919uL, 15236432095734105306uL, 2538748850867346054uL, 11856293991052060216uL, 13021741769935452261uL, 15990798677628125186uL, 763205940277591432uL, 14016609120497251219uL,
|
||||
10061287064328956494uL, 3093811003563252786uL, 4790004205042634049uL, 8356374131917757362uL, 525807322001048172uL, 9973800865292223322uL, 8060006530596508447uL, 14306696413404433091uL, 4971791225320957497uL, 16356195123205149225uL,
|
||||
11676952182109293888uL, 1866917567049488617uL, 17601962695443621644uL, 4878334347704591445uL, 15577684812609376326uL, 5838476093026002976uL, 16661444707372843629uL, 585131888633540512uL, 4258502335484898171uL, 9216164226481474882uL,
|
||||
1051613531605566680uL, 9311100443926583238uL, 12786619038457767969uL, 7592012931346331751uL, 17784440428065453348uL, 1921896258116084693uL, 3288584640079142494uL, 182885720694182440uL, 10430896929374429327uL, 4347442274373970199uL,
|
||||
12254875670338446048uL, 470303682846092152uL, 15755474228186677870uL, 14073238624926194311uL, 7877737635941138743uL, 18183412781327927468uL, 8981595325954651774uL, 18092225707227040448uL, 13829189599099727097uL, 7536474657577537907uL,
|
||||
14599035985023753267uL, 13539018426536891817uL, 998525038457700324uL, 8121292137418072206uL, 16463535689691560273uL, 10154726272180381730uL, 17216498010023871705uL, 1689003026191473713uL, 6955846591918243539uL, 12968836256081541641uL,
|
||||
10451497052958755227uL, 1104161065046732236uL, 5822238831865856308uL, 7770259743761115727uL, 10722677434777197023uL, 3109098905151763750uL, 7477148998953467071uL, 5270373732550072797uL, 235152363269307196uL, 2264823631868769169uL,
|
||||
11566760878849073000uL, 15293842507372922550uL, 129144564315678996uL, 12435787444463389080uL, 6107963510664673380uL, 2809900646717377218uL, 16044592061068688190uL, 292565944326076752uL, 16550986154605973573uL, 17513004949887526240uL,
|
||||
7062097245496290555uL, 16747641319377612705uL, 14707889229881751371uL, 6021262719684655624uL, 1972895747902540481uL, 3945791491441759391uL, 8801111098641915142uL, 13700503016009418221uL, 14942809973861092471uL, 17799868517652798512uL,
|
||||
5560617129282953357uL, 6890080809738628344uL, 2627701227983280362uL, 9690522075866191274uL, 5539875718724946329uL, 0uL, 17034008114061809393uL, 13077421330682024305uL, 13963290176307300527uL, 7299656588959035031uL,
|
||||
1583357035284794905uL, 13305652357639548565uL, 12200671035189303772uL, 6400302286636641940uL, 6420058603497817984uL, 6691528990365472708uL, 9400350877559778554uL, 15130709207736669938uL, 9038681643377794922uL, 13132277426487405133uL,
|
||||
4440522822651396099uL, 8411535559894538718uL, 16096717416137511466uL, 4238992274866487919uL, 18077078508495971284uL, 13838789949392609723uL, 9599646529712778902uL, 14123892125294942443uL, 5169063728564034821uL, 12670779828505572004uL,
|
||||
10920656821177770723uL, 13361612877962987393uL, 2428230993188407470uL, 3570877924549138163uL, 14885899578566174051uL, 4060646644394037319uL, 3855408526229221283uL, 16641794458759736185uL, 16173936262127370241uL, 8928671747737777170uL,
|
||||
1348049825574685813uL, 3677174894530839771uL, 10353696833961841438uL, 15701199224267946322uL, 8644847306339132130uL, 2719514554751545854uL, 8462570783810646218uL, 1405101508380157281uL, 3478079366649118695uL, 11907751461527015212uL,
|
||||
15861795400831396118uL, 6598086612559222184uL, 12839867613895398173uL, 3768380308409468599uL, 6708048310613262032uL, 1739040292966674941uL, 11410407946413892695uL, 11121233283590249735uL, 11801135715313362004uL, 9091840505278506070uL,
|
||||
9777726215814167742uL, 4700331558701315709uL, 11030972914175796795uL, 4679309188558905193uL, 2030323828767328429uL, 5649811934742993841uL, 415940168518455364uL, 16266875523426953493uL, 17492088132592553076uL, 13255757203528008537uL,
|
||||
7190925116101314031uL, 11320506052158021483uL, 16372326831517072189uL, 15417076028166565794uL, 17693635250630774296uL, 5077496726762238993uL, 2339654594279481786uL, 13646640466407096017uL, 12546315335725685680uL, 18361677116664093316uL,
|
||||
6127437837148246384uL, 3002776577694476046uL, 12090310421094014212uL, 10260721838532639242uL, 1294312070793836361uL, 15527788568662064522uL, 17232911777424223693uL, 5255402455948538057uL, 2517972805691405202uL, 7008429859484506055uL,
|
||||
5361338717396067041uL, 9294722410648223442uL, 8178097563976550810uL, 10629217130044840883uL, 9863923954178969970uL, 2824906557929530326uL
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Gost3411_2012_256Digest : Gost3411_2012Digest
|
||||
{
|
||||
private static readonly byte[] IV = new byte[64]
|
||||
{
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1
|
||||
};
|
||||
|
||||
public override string AlgorithmName => "GOST3411-2012-256";
|
||||
|
||||
public Gost3411_2012_256Digest()
|
||||
: base(IV)
|
||||
{
|
||||
}
|
||||
|
||||
public Gost3411_2012_256Digest(Gost3411_2012_256Digest other)
|
||||
: base(IV)
|
||||
{
|
||||
Reset(other);
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
byte[] array = new byte[64];
|
||||
base.DoFinal(array, 0);
|
||||
Array.Copy(array, 32, output, outOff, 32);
|
||||
return 32;
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new Gost3411_2012_256Digest(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Gost3411_2012_512Digest : Gost3411_2012Digest
|
||||
{
|
||||
private static readonly byte[] IV;
|
||||
|
||||
public override string AlgorithmName => "GOST3411-2012-512";
|
||||
|
||||
public Gost3411_2012_512Digest()
|
||||
: base(IV)
|
||||
{
|
||||
}
|
||||
|
||||
public Gost3411_2012_512Digest(Gost3411_2012_512Digest other)
|
||||
: base(IV)
|
||||
{
|
||||
Reset(other);
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new Gost3411_2012_512Digest(this);
|
||||
}
|
||||
|
||||
static Gost3411_2012_512Digest()
|
||||
{
|
||||
byte[] iV = new byte[64];
|
||||
IV = iV;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,435 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class KeccakDigest : IDigest, IMemoable
|
||||
{
|
||||
private static readonly ulong[] KeccakRoundConstants = new ulong[24]
|
||||
{
|
||||
1uL, 32898uL, 9223372036854808714uL, 9223372039002292224uL, 32907uL, 2147483649uL, 9223372039002292353uL, 9223372036854808585uL, 138uL, 136uL,
|
||||
2147516425uL, 2147483658uL, 2147516555uL, 9223372036854775947uL, 9223372036854808713uL, 9223372036854808579uL, 9223372036854808578uL, 9223372036854775936uL, 32778uL, 9223372039002259466uL,
|
||||
9223372039002292353uL, 9223372036854808704uL, 2147483649uL, 9223372039002292232uL
|
||||
};
|
||||
|
||||
private ulong[] state = new ulong[25];
|
||||
|
||||
protected byte[] dataQueue = new byte[192];
|
||||
|
||||
protected int rate;
|
||||
|
||||
protected int bitsInQueue;
|
||||
|
||||
protected int fixedOutputLength;
|
||||
|
||||
protected bool squeezing;
|
||||
|
||||
public virtual string AlgorithmName => "Keccak-" + fixedOutputLength;
|
||||
|
||||
public KeccakDigest()
|
||||
: this(288)
|
||||
{
|
||||
}
|
||||
|
||||
public KeccakDigest(int bitLength)
|
||||
{
|
||||
Init(bitLength);
|
||||
}
|
||||
|
||||
public KeccakDigest(KeccakDigest source)
|
||||
{
|
||||
CopyIn(source);
|
||||
}
|
||||
|
||||
private void CopyIn(KeccakDigest source)
|
||||
{
|
||||
Array.Copy(source.state, 0, state, 0, source.state.Length);
|
||||
Array.Copy(source.dataQueue, 0, dataQueue, 0, source.dataQueue.Length);
|
||||
rate = source.rate;
|
||||
bitsInQueue = source.bitsInQueue;
|
||||
fixedOutputLength = source.fixedOutputLength;
|
||||
squeezing = source.squeezing;
|
||||
}
|
||||
|
||||
public virtual int GetDigestSize()
|
||||
{
|
||||
return fixedOutputLength >> 3;
|
||||
}
|
||||
|
||||
public virtual void Update(byte input)
|
||||
{
|
||||
Absorb(new byte[1] { input }, 0, 1);
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] input, int inOff, int len)
|
||||
{
|
||||
Absorb(input, inOff, len);
|
||||
}
|
||||
|
||||
public virtual int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Squeeze(output, outOff, fixedOutputLength);
|
||||
Reset();
|
||||
return GetDigestSize();
|
||||
}
|
||||
|
||||
protected virtual int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits)
|
||||
{
|
||||
if (partialBits > 0)
|
||||
{
|
||||
AbsorbBits(partialByte, partialBits);
|
||||
}
|
||||
Squeeze(output, outOff, fixedOutputLength);
|
||||
Reset();
|
||||
return GetDigestSize();
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
Init(fixedOutputLength);
|
||||
}
|
||||
|
||||
public virtual int GetByteLength()
|
||||
{
|
||||
return rate >> 3;
|
||||
}
|
||||
|
||||
private void Init(int bitLength)
|
||||
{
|
||||
switch (bitLength)
|
||||
{
|
||||
case 128:
|
||||
case 224:
|
||||
case 256:
|
||||
case 288:
|
||||
case 384:
|
||||
case 512:
|
||||
InitSponge(1600 - (bitLength << 1));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("must be one of 128, 224, 256, 288, 384, or 512.", "bitLength");
|
||||
}
|
||||
}
|
||||
|
||||
private void InitSponge(int rate)
|
||||
{
|
||||
if (rate <= 0 || rate >= 1600 || (rate & 0x3F) != 0)
|
||||
{
|
||||
throw new InvalidOperationException("invalid rate value");
|
||||
}
|
||||
this.rate = rate;
|
||||
Array.Clear(state, 0, state.Length);
|
||||
Arrays.Fill(dataQueue, 0);
|
||||
bitsInQueue = 0;
|
||||
squeezing = false;
|
||||
fixedOutputLength = 1600 - rate >> 1;
|
||||
}
|
||||
|
||||
protected void Absorb(byte[] data, int off, int len)
|
||||
{
|
||||
if ((bitsInQueue & 7) != 0)
|
||||
{
|
||||
throw new InvalidOperationException("attempt to absorb with odd length queue");
|
||||
}
|
||||
if (squeezing)
|
||||
{
|
||||
throw new InvalidOperationException("attempt to absorb while squeezing");
|
||||
}
|
||||
int num = bitsInQueue >> 3;
|
||||
int num2 = rate >> 3;
|
||||
int num3 = 0;
|
||||
while (num3 < len)
|
||||
{
|
||||
if (num == 0 && num3 <= len - num2)
|
||||
{
|
||||
do
|
||||
{
|
||||
KeccakAbsorb(data, off + num3);
|
||||
num3 += num2;
|
||||
}
|
||||
while (num3 <= len - num2);
|
||||
continue;
|
||||
}
|
||||
int num4 = System.Math.Min(num2 - num, len - num3);
|
||||
Array.Copy(data, off + num3, dataQueue, num, num4);
|
||||
num += num4;
|
||||
num3 += num4;
|
||||
if (num == num2)
|
||||
{
|
||||
KeccakAbsorb(dataQueue, 0);
|
||||
num = 0;
|
||||
}
|
||||
}
|
||||
bitsInQueue = num << 3;
|
||||
}
|
||||
|
||||
protected void AbsorbBits(int data, int bits)
|
||||
{
|
||||
if (bits < 1 || bits > 7)
|
||||
{
|
||||
throw new ArgumentException("must be in the range 1 to 7", "bits");
|
||||
}
|
||||
if ((bitsInQueue & 7) != 0)
|
||||
{
|
||||
throw new InvalidOperationException("attempt to absorb with odd length queue");
|
||||
}
|
||||
if (squeezing)
|
||||
{
|
||||
throw new InvalidOperationException("attempt to absorb while squeezing");
|
||||
}
|
||||
int num = (1 << bits) - 1;
|
||||
dataQueue[bitsInQueue >> 3] = (byte)(data & num);
|
||||
bitsInQueue += bits;
|
||||
}
|
||||
|
||||
private void PadAndSwitchToSqueezingPhase()
|
||||
{
|
||||
byte[] array2;
|
||||
byte[] array = (array2 = dataQueue);
|
||||
int num = bitsInQueue >> 3;
|
||||
nint num2 = num;
|
||||
array[num] = (byte)(array2[num2] | (byte)(1 << (bitsInQueue & 7)));
|
||||
if (++bitsInQueue == rate)
|
||||
{
|
||||
KeccakAbsorb(dataQueue, 0);
|
||||
bitsInQueue = 0;
|
||||
}
|
||||
int num3 = bitsInQueue >> 6;
|
||||
int num4 = bitsInQueue & 0x3F;
|
||||
int num5 = 0;
|
||||
ulong[] array4;
|
||||
for (int i = 0; i < num3; i++)
|
||||
{
|
||||
ulong[] array3 = (array4 = state);
|
||||
int num6 = i;
|
||||
num2 = num6;
|
||||
array3[num6] = array4[num2] ^ Pack.LE_To_UInt64(dataQueue, num5);
|
||||
num5 += 8;
|
||||
}
|
||||
if (num4 > 0)
|
||||
{
|
||||
ulong num7 = (ulong)((1L << num4) - 1);
|
||||
ulong[] array5 = (array4 = state);
|
||||
num2 = num3;
|
||||
array5[num3] = array4[num2] ^ (Pack.LE_To_UInt64(dataQueue, num5) & num7);
|
||||
}
|
||||
ulong[] array6 = (array4 = state);
|
||||
int num8 = rate - 1 >> 6;
|
||||
num2 = num8;
|
||||
array6[num8] = array4[num2] ^ 0x8000000000000000uL;
|
||||
KeccakPermutation();
|
||||
KeccakExtract();
|
||||
bitsInQueue = rate;
|
||||
squeezing = true;
|
||||
}
|
||||
|
||||
protected void Squeeze(byte[] output, int offset, long outputLength)
|
||||
{
|
||||
if (!squeezing)
|
||||
{
|
||||
PadAndSwitchToSqueezingPhase();
|
||||
}
|
||||
if ((outputLength & 7) != 0)
|
||||
{
|
||||
throw new InvalidOperationException("outputLength not a multiple of 8");
|
||||
}
|
||||
int num2;
|
||||
for (long num = 0L; num < outputLength; num += num2)
|
||||
{
|
||||
if (bitsInQueue == 0)
|
||||
{
|
||||
KeccakPermutation();
|
||||
KeccakExtract();
|
||||
bitsInQueue = rate;
|
||||
}
|
||||
num2 = (int)System.Math.Min(bitsInQueue, outputLength - num);
|
||||
Array.Copy(dataQueue, rate - bitsInQueue >> 3, output, offset + (int)(num >> 3), num2 >> 3);
|
||||
bitsInQueue -= num2;
|
||||
}
|
||||
}
|
||||
|
||||
private void KeccakAbsorb(byte[] data, int off)
|
||||
{
|
||||
int num = rate >> 6;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
ulong[] array2;
|
||||
ulong[] array = (array2 = state);
|
||||
int num2 = i;
|
||||
nint num3 = num2;
|
||||
array[num2] = array2[num3] ^ Pack.LE_To_UInt64(data, off);
|
||||
off += 8;
|
||||
}
|
||||
KeccakPermutation();
|
||||
}
|
||||
|
||||
private void KeccakExtract()
|
||||
{
|
||||
Pack.UInt64_To_LE(state, 0, rate >> 6, dataQueue, 0);
|
||||
}
|
||||
|
||||
private void KeccakPermutation()
|
||||
{
|
||||
ulong[] array = state;
|
||||
ulong num = array[0];
|
||||
ulong num2 = array[1];
|
||||
ulong num3 = array[2];
|
||||
ulong num4 = array[3];
|
||||
ulong num5 = array[4];
|
||||
ulong num6 = array[5];
|
||||
ulong num7 = array[6];
|
||||
ulong num8 = array[7];
|
||||
ulong num9 = array[8];
|
||||
ulong num10 = array[9];
|
||||
ulong num11 = array[10];
|
||||
ulong num12 = array[11];
|
||||
ulong num13 = array[12];
|
||||
ulong num14 = array[13];
|
||||
ulong num15 = array[14];
|
||||
ulong num16 = array[15];
|
||||
ulong num17 = array[16];
|
||||
ulong num18 = array[17];
|
||||
ulong num19 = array[18];
|
||||
ulong num20 = array[19];
|
||||
ulong num21 = array[20];
|
||||
ulong num22 = array[21];
|
||||
ulong num23 = array[22];
|
||||
ulong num24 = array[23];
|
||||
ulong num25 = array[24];
|
||||
for (int i = 0; i < 24; i++)
|
||||
{
|
||||
ulong num26 = num ^ num6 ^ num11 ^ num16 ^ num21;
|
||||
ulong num27 = num2 ^ num7 ^ num12 ^ num17 ^ num22;
|
||||
ulong num28 = num3 ^ num8 ^ num13 ^ num18 ^ num23;
|
||||
ulong num29 = num4 ^ num9 ^ num14 ^ num19 ^ num24;
|
||||
ulong num30 = num5 ^ num10 ^ num15 ^ num20 ^ num25;
|
||||
ulong num31 = ((num27 << 1) | (num27 >> 63)) ^ num30;
|
||||
ulong num32 = ((num28 << 1) | (num28 >> 63)) ^ num26;
|
||||
ulong num33 = ((num29 << 1) | (num29 >> 63)) ^ num27;
|
||||
ulong num34 = ((num30 << 1) | (num30 >> 63)) ^ num28;
|
||||
ulong num35 = ((num26 << 1) | (num26 >> 63)) ^ num29;
|
||||
num ^= num31;
|
||||
num6 ^= num31;
|
||||
num11 ^= num31;
|
||||
num16 ^= num31;
|
||||
num21 ^= num31;
|
||||
num2 ^= num32;
|
||||
num7 ^= num32;
|
||||
num12 ^= num32;
|
||||
num17 ^= num32;
|
||||
num22 ^= num32;
|
||||
num3 ^= num33;
|
||||
num8 ^= num33;
|
||||
num13 ^= num33;
|
||||
num18 ^= num33;
|
||||
num23 ^= num33;
|
||||
num4 ^= num34;
|
||||
num9 ^= num34;
|
||||
num14 ^= num34;
|
||||
num19 ^= num34;
|
||||
num24 ^= num34;
|
||||
num5 ^= num35;
|
||||
num10 ^= num35;
|
||||
num15 ^= num35;
|
||||
num20 ^= num35;
|
||||
num25 ^= num35;
|
||||
num27 = (num2 << 1) | (num2 >> 63);
|
||||
num2 = (num7 << 44) | (num7 >> 20);
|
||||
num7 = (num10 << 20) | (num10 >> 44);
|
||||
num10 = (num23 << 61) | (num23 >> 3);
|
||||
num23 = (num15 << 39) | (num15 >> 25);
|
||||
num15 = (num21 << 18) | (num21 >> 46);
|
||||
num21 = (num3 << 62) | (num3 >> 2);
|
||||
num3 = (num13 << 43) | (num13 >> 21);
|
||||
num13 = (num14 << 25) | (num14 >> 39);
|
||||
num14 = (num20 << 8) | (num20 >> 56);
|
||||
num20 = (num24 << 56) | (num24 >> 8);
|
||||
num24 = (num16 << 41) | (num16 >> 23);
|
||||
num16 = (num5 << 27) | (num5 >> 37);
|
||||
num5 = (num25 << 14) | (num25 >> 50);
|
||||
num25 = (num22 << 2) | (num22 >> 62);
|
||||
num22 = (num9 << 55) | (num9 >> 9);
|
||||
num9 = (num17 << 45) | (num17 >> 19);
|
||||
num17 = (num6 << 36) | (num6 >> 28);
|
||||
num6 = (num4 << 28) | (num4 >> 36);
|
||||
num4 = (num19 << 21) | (num19 >> 43);
|
||||
num19 = (num18 << 15) | (num18 >> 49);
|
||||
num18 = (num12 << 10) | (num12 >> 54);
|
||||
num12 = (num8 << 6) | (num8 >> 58);
|
||||
num8 = (num11 << 3) | (num11 >> 61);
|
||||
num11 = num27;
|
||||
num26 = num ^ (~num2 & num3);
|
||||
num27 = num2 ^ (~num3 & num4);
|
||||
num3 ^= ~num4 & num5;
|
||||
num4 ^= ~num5 & num;
|
||||
num5 ^= ~num & num2;
|
||||
num = num26;
|
||||
num2 = num27;
|
||||
num26 = num6 ^ (~num7 & num8);
|
||||
num27 = num7 ^ (~num8 & num9);
|
||||
num8 ^= ~num9 & num10;
|
||||
num9 ^= ~num10 & num6;
|
||||
num10 ^= ~num6 & num7;
|
||||
num6 = num26;
|
||||
num7 = num27;
|
||||
num26 = num11 ^ (~num12 & num13);
|
||||
num27 = num12 ^ (~num13 & num14);
|
||||
num13 ^= ~num14 & num15;
|
||||
num14 ^= ~num15 & num11;
|
||||
num15 ^= ~num11 & num12;
|
||||
num11 = num26;
|
||||
num12 = num27;
|
||||
num26 = num16 ^ (~num17 & num18);
|
||||
num27 = num17 ^ (~num18 & num19);
|
||||
num18 ^= ~num19 & num20;
|
||||
num19 ^= ~num20 & num16;
|
||||
num20 ^= ~num16 & num17;
|
||||
num16 = num26;
|
||||
num17 = num27;
|
||||
num26 = num21 ^ (~num22 & num23);
|
||||
num27 = num22 ^ (~num23 & num24);
|
||||
num23 ^= ~num24 & num25;
|
||||
num24 ^= ~num25 & num21;
|
||||
num25 ^= ~num21 & num22;
|
||||
num21 = num26;
|
||||
num22 = num27;
|
||||
num ^= KeccakRoundConstants[i];
|
||||
}
|
||||
array[0] = num;
|
||||
array[1] = num2;
|
||||
array[2] = num3;
|
||||
array[3] = num4;
|
||||
array[4] = num5;
|
||||
array[5] = num6;
|
||||
array[6] = num7;
|
||||
array[7] = num8;
|
||||
array[8] = num9;
|
||||
array[9] = num10;
|
||||
array[10] = num11;
|
||||
array[11] = num12;
|
||||
array[12] = num13;
|
||||
array[13] = num14;
|
||||
array[14] = num15;
|
||||
array[15] = num16;
|
||||
array[16] = num17;
|
||||
array[17] = num18;
|
||||
array[18] = num19;
|
||||
array[19] = num20;
|
||||
array[20] = num21;
|
||||
array[21] = num22;
|
||||
array[22] = num23;
|
||||
array[23] = num24;
|
||||
array[24] = num25;
|
||||
}
|
||||
|
||||
public virtual IMemoable Copy()
|
||||
{
|
||||
return new KeccakDigest(this);
|
||||
}
|
||||
|
||||
public virtual void Reset(IMemoable other)
|
||||
{
|
||||
CopyIn((KeccakDigest)other);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public abstract class LongDigest : IDigest, IMemoable
|
||||
{
|
||||
private int MyByteLength = 128;
|
||||
|
||||
private byte[] xBuf;
|
||||
|
||||
private int xBufOff;
|
||||
|
||||
private long byteCount1;
|
||||
|
||||
private long byteCount2;
|
||||
|
||||
internal ulong H1;
|
||||
|
||||
internal ulong H2;
|
||||
|
||||
internal ulong H3;
|
||||
|
||||
internal ulong H4;
|
||||
|
||||
internal ulong H5;
|
||||
|
||||
internal ulong H6;
|
||||
|
||||
internal ulong H7;
|
||||
|
||||
internal ulong H8;
|
||||
|
||||
private ulong[] W = new ulong[80];
|
||||
|
||||
private int wOff;
|
||||
|
||||
internal static readonly ulong[] K = new ulong[80]
|
||||
{
|
||||
4794697086780616226uL, 8158064640168781261uL, 13096744586834688815uL, 16840607885511220156uL, 4131703408338449720uL, 6480981068601479193uL, 10538285296894168987uL, 12329834152419229976uL, 15566598209576043074uL, 1334009975649890238uL,
|
||||
2608012711638119052uL, 6128411473006802146uL, 8268148722764581231uL, 9286055187155687089uL, 11230858885718282805uL, 13951009754708518548uL, 16472876342353939154uL, 17275323862435702243uL, 1135362057144423861uL, 2597628984639134821uL,
|
||||
3308224258029322869uL, 5365058923640841347uL, 6679025012923562964uL, 8573033837759648693uL, 10970295158949994411uL, 12119686244451234320uL, 12683024718118986047uL, 13788192230050041572uL, 14330467153632333762uL, 15395433587784984357uL,
|
||||
489312712824947311uL, 1452737877330783856uL, 2861767655752347644uL, 3322285676063803686uL, 5560940570517711597uL, 5996557281743188959uL, 7280758554555802590uL, 8532644243296465576uL, 9350256976987008742uL, 10552545826968843579uL,
|
||||
11727347734174303076uL, 12113106623233404929uL, 14000437183269869457uL, 14369950271660146224uL, 15101387698204529176uL, 15463397548674623760uL, 17586052441742319658uL, 1182934255886127544uL, 1847814050463011016uL, 2177327727835720531uL,
|
||||
2830643537854262169uL, 3796741975233480872uL, 4115178125766777443uL, 5681478168544905931uL, 6601373596472566643uL, 7507060721942968483uL, 8399075790359081724uL, 8693463985226723168uL, 9568029438360202098uL, 10144078919501101548uL,
|
||||
10430055236837252648uL, 11840083180663258601uL, 13761210420658862357uL, 14299343276471374635uL, 14566680578165727644uL, 15097957966210449927uL, 16922976911328602910uL, 17689382322260857208uL, 500013540394364858uL, 748580250866718886uL,
|
||||
1242879168328830382uL, 1977374033974150939uL, 2944078676154940804uL, 3659926193048069267uL, 4368137639120453308uL, 4836135668995329356uL, 5532061633213252278uL, 6448918945643986474uL, 6902733635092675308uL, 7801388544844847127uL
|
||||
};
|
||||
|
||||
public abstract string AlgorithmName { get; }
|
||||
|
||||
internal LongDigest()
|
||||
{
|
||||
xBuf = new byte[8];
|
||||
Reset();
|
||||
}
|
||||
|
||||
internal LongDigest(LongDigest t)
|
||||
{
|
||||
xBuf = new byte[t.xBuf.Length];
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
protected void CopyIn(LongDigest t)
|
||||
{
|
||||
Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
|
||||
xBufOff = t.xBufOff;
|
||||
byteCount1 = t.byteCount1;
|
||||
byteCount2 = t.byteCount2;
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
H4 = t.H4;
|
||||
H5 = t.H5;
|
||||
H6 = t.H6;
|
||||
H7 = t.H7;
|
||||
H8 = t.H8;
|
||||
Array.Copy(t.W, 0, W, 0, t.W.Length);
|
||||
wOff = t.wOff;
|
||||
}
|
||||
|
||||
public void Update(byte input)
|
||||
{
|
||||
xBuf[xBufOff++] = input;
|
||||
if (xBufOff == xBuf.Length)
|
||||
{
|
||||
ProcessWord(xBuf, 0);
|
||||
xBufOff = 0;
|
||||
}
|
||||
byteCount1++;
|
||||
}
|
||||
|
||||
public void BlockUpdate(byte[] input, int inOff, int length)
|
||||
{
|
||||
while (xBufOff != 0 && length > 0)
|
||||
{
|
||||
Update(input[inOff]);
|
||||
inOff++;
|
||||
length--;
|
||||
}
|
||||
while (length > xBuf.Length)
|
||||
{
|
||||
ProcessWord(input, inOff);
|
||||
inOff += xBuf.Length;
|
||||
length -= xBuf.Length;
|
||||
byteCount1 += xBuf.Length;
|
||||
}
|
||||
while (length > 0)
|
||||
{
|
||||
Update(input[inOff]);
|
||||
inOff++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
public void Finish()
|
||||
{
|
||||
AdjustByteCounts();
|
||||
long lowW = byteCount1 << 3;
|
||||
long hiW = byteCount2;
|
||||
Update(128);
|
||||
while (xBufOff != 0)
|
||||
{
|
||||
Update(0);
|
||||
}
|
||||
ProcessLength(lowW, hiW);
|
||||
ProcessBlock();
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
byteCount1 = 0L;
|
||||
byteCount2 = 0L;
|
||||
xBufOff = 0;
|
||||
for (int i = 0; i < xBuf.Length; i++)
|
||||
{
|
||||
xBuf[i] = 0;
|
||||
}
|
||||
wOff = 0;
|
||||
Array.Clear(W, 0, W.Length);
|
||||
}
|
||||
|
||||
internal void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
W[wOff] = Pack.BE_To_UInt64(input, inOff);
|
||||
if (++wOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustByteCounts()
|
||||
{
|
||||
if (byteCount1 > 2305843009213693951L)
|
||||
{
|
||||
byteCount2 += byteCount1 >>> 61;
|
||||
byteCount1 &= 2305843009213693951L;
|
||||
}
|
||||
}
|
||||
|
||||
internal void ProcessLength(long lowW, long hiW)
|
||||
{
|
||||
if (wOff > 14)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
W[14] = (ulong)hiW;
|
||||
W[15] = (ulong)lowW;
|
||||
}
|
||||
|
||||
internal void ProcessBlock()
|
||||
{
|
||||
AdjustByteCounts();
|
||||
for (int i = 16; i <= 79; i++)
|
||||
{
|
||||
W[i] = Sigma1(W[i - 2]) + W[i - 7] + Sigma0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
ulong num = H1;
|
||||
ulong num2 = H2;
|
||||
ulong num3 = H3;
|
||||
ulong num4 = H4;
|
||||
ulong num5 = H5;
|
||||
ulong num6 = H6;
|
||||
ulong num7 = H7;
|
||||
ulong num8 = H8;
|
||||
int num9 = 0;
|
||||
for (int j = 0; j < 10; j++)
|
||||
{
|
||||
num8 += Sum1(num5) + Ch(num5, num6, num7) + K[num9] + W[num9++];
|
||||
num4 += num8;
|
||||
num8 += Sum0(num) + Maj(num, num2, num3);
|
||||
num7 += Sum1(num4) + Ch(num4, num5, num6) + K[num9] + W[num9++];
|
||||
num3 += num7;
|
||||
num7 += Sum0(num8) + Maj(num8, num, num2);
|
||||
num6 += Sum1(num3) + Ch(num3, num4, num5) + K[num9] + W[num9++];
|
||||
num2 += num6;
|
||||
num6 += Sum0(num7) + Maj(num7, num8, num);
|
||||
num5 += Sum1(num2) + Ch(num2, num3, num4) + K[num9] + W[num9++];
|
||||
num += num5;
|
||||
num5 += Sum0(num6) + Maj(num6, num7, num8);
|
||||
num4 += Sum1(num) + Ch(num, num2, num3) + K[num9] + W[num9++];
|
||||
num8 += num4;
|
||||
num4 += Sum0(num5) + Maj(num5, num6, num7);
|
||||
num3 += Sum1(num8) + Ch(num8, num, num2) + K[num9] + W[num9++];
|
||||
num7 += num3;
|
||||
num3 += Sum0(num4) + Maj(num4, num5, num6);
|
||||
num2 += Sum1(num7) + Ch(num7, num8, num) + K[num9] + W[num9++];
|
||||
num6 += num2;
|
||||
num2 += Sum0(num3) + Maj(num3, num4, num5);
|
||||
num += Sum1(num6) + Ch(num6, num7, num8) + K[num9] + W[num9++];
|
||||
num5 += num;
|
||||
num += Sum0(num2) + Maj(num2, num3, num4);
|
||||
}
|
||||
H1 += num;
|
||||
H2 += num2;
|
||||
H3 += num3;
|
||||
H4 += num4;
|
||||
H5 += num5;
|
||||
H6 += num6;
|
||||
H7 += num7;
|
||||
H8 += num8;
|
||||
wOff = 0;
|
||||
Array.Clear(W, 0, 16);
|
||||
}
|
||||
|
||||
private static ulong Ch(ulong x, ulong y, ulong z)
|
||||
{
|
||||
return (x & y) ^ (~x & z);
|
||||
}
|
||||
|
||||
private static ulong Maj(ulong x, ulong y, ulong z)
|
||||
{
|
||||
return (x & y) ^ (x & z) ^ (y & z);
|
||||
}
|
||||
|
||||
private static ulong Sum0(ulong x)
|
||||
{
|
||||
return ((x << 36) | (x >> 28)) ^ ((x << 30) | (x >> 34)) ^ ((x << 25) | (x >> 39));
|
||||
}
|
||||
|
||||
private static ulong Sum1(ulong x)
|
||||
{
|
||||
return ((x << 50) | (x >> 14)) ^ ((x << 46) | (x >> 18)) ^ ((x << 23) | (x >> 41));
|
||||
}
|
||||
|
||||
private static ulong Sigma0(ulong x)
|
||||
{
|
||||
return ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7);
|
||||
}
|
||||
|
||||
private static ulong Sigma1(ulong x)
|
||||
{
|
||||
return ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6);
|
||||
}
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return MyByteLength;
|
||||
}
|
||||
|
||||
public abstract int GetDigestSize();
|
||||
|
||||
public abstract int DoFinal(byte[] output, int outOff);
|
||||
|
||||
public abstract IMemoable Copy();
|
||||
|
||||
public abstract void Reset(IMemoable t);
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class MD2Digest : IDigest, IMemoable
|
||||
{
|
||||
private const int DigestLength = 16;
|
||||
|
||||
private const int BYTE_LENGTH = 16;
|
||||
|
||||
private byte[] X = new byte[48];
|
||||
|
||||
private int xOff;
|
||||
|
||||
private byte[] M = new byte[16];
|
||||
|
||||
private int mOff;
|
||||
|
||||
private byte[] C = new byte[16];
|
||||
|
||||
private int COff;
|
||||
|
||||
private static readonly byte[] S = new byte[256]
|
||||
{
|
||||
41, 46, 67, 201, 162, 216, 124, 1, 61, 54,
|
||||
84, 161, 236, 240, 6, 19, 98, 167, 5, 243,
|
||||
192, 199, 115, 140, 152, 147, 43, 217, 188, 76,
|
||||
130, 202, 30, 155, 87, 60, 253, 212, 224, 22,
|
||||
103, 66, 111, 24, 138, 23, 229, 18, 190, 78,
|
||||
196, 214, 218, 158, 222, 73, 160, 251, 245, 142,
|
||||
187, 47, 238, 122, 169, 104, 121, 145, 21, 178,
|
||||
7, 63, 148, 194, 16, 137, 11, 34, 95, 33,
|
||||
128, 127, 93, 154, 90, 144, 50, 39, 53, 62,
|
||||
204, 231, 191, 247, 151, 3, 255, 25, 48, 179,
|
||||
72, 165, 181, 209, 215, 94, 146, 42, 172, 86,
|
||||
170, 198, 79, 184, 56, 210, 150, 164, 125, 182,
|
||||
118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
||||
112, 89, 100, 113, 135, 32, 134, 91, 207, 101,
|
||||
230, 45, 168, 2, 27, 96, 37, 173, 174, 176,
|
||||
185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
||||
85, 71, 163, 35, 221, 81, 175, 58, 195, 92,
|
||||
249, 206, 186, 197, 234, 38, 44, 83, 13, 110,
|
||||
133, 40, 132, 9, 211, 223, 205, 244, 65, 129,
|
||||
77, 82, 106, 220, 55, 200, 108, 193, 171, 250,
|
||||
36, 225, 123, 8, 12, 189, 177, 74, 120, 136,
|
||||
149, 139, 227, 99, 232, 109, 233, 203, 213, 254,
|
||||
59, 0, 29, 57, 242, 239, 183, 14, 102, 88,
|
||||
208, 228, 166, 119, 114, 248, 235, 117, 75, 10,
|
||||
49, 68, 80, 180, 143, 237, 31, 26, 219, 153,
|
||||
141, 51, 159, 17, 131, 20
|
||||
};
|
||||
|
||||
public string AlgorithmName => "MD2";
|
||||
|
||||
public MD2Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public MD2Digest(MD2Digest t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(MD2Digest t)
|
||||
{
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
Array.Copy(t.M, 0, M, 0, t.M.Length);
|
||||
mOff = t.mOff;
|
||||
Array.Copy(t.C, 0, C, 0, t.C.Length);
|
||||
COff = t.COff;
|
||||
}
|
||||
|
||||
public int GetDigestSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
byte b = (byte)(M.Length - mOff);
|
||||
for (int i = mOff; i < M.Length; i++)
|
||||
{
|
||||
M[i] = b;
|
||||
}
|
||||
ProcessChecksum(M);
|
||||
ProcessBlock(M);
|
||||
ProcessBlock(C);
|
||||
Array.Copy(X, xOff, output, outOff, 16);
|
||||
Reset();
|
||||
return 16;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
mOff = 0;
|
||||
for (int j = 0; j != M.Length; j++)
|
||||
{
|
||||
M[j] = 0;
|
||||
}
|
||||
COff = 0;
|
||||
for (int k = 0; k != C.Length; k++)
|
||||
{
|
||||
C[k] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(byte input)
|
||||
{
|
||||
M[mOff++] = input;
|
||||
if (mOff == 16)
|
||||
{
|
||||
ProcessChecksum(M);
|
||||
ProcessBlock(M);
|
||||
mOff = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void BlockUpdate(byte[] input, int inOff, int length)
|
||||
{
|
||||
while (mOff != 0 && length > 0)
|
||||
{
|
||||
Update(input[inOff]);
|
||||
inOff++;
|
||||
length--;
|
||||
}
|
||||
while (length > 16)
|
||||
{
|
||||
Array.Copy(input, inOff, M, 0, 16);
|
||||
ProcessChecksum(M);
|
||||
ProcessBlock(M);
|
||||
length -= 16;
|
||||
inOff += 16;
|
||||
}
|
||||
while (length > 0)
|
||||
{
|
||||
Update(input[inOff]);
|
||||
inOff++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
internal void ProcessChecksum(byte[] m)
|
||||
{
|
||||
int num = C[15];
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
byte[] c;
|
||||
byte[] array = (c = C);
|
||||
int num2 = i;
|
||||
nint num3 = num2;
|
||||
array[num2] = (byte)(c[num3] ^ S[(m[i] ^ num) & 0xFF]);
|
||||
num = C[i];
|
||||
}
|
||||
}
|
||||
|
||||
internal void ProcessBlock(byte[] m)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
X[i + 16] = m[i];
|
||||
X[i + 32] = (byte)(m[i] ^ X[i]);
|
||||
}
|
||||
int num = 0;
|
||||
for (int j = 0; j < 18; j++)
|
||||
{
|
||||
for (int k = 0; k < 48; k++)
|
||||
{
|
||||
byte[] x;
|
||||
byte[] array = (x = X);
|
||||
int num2 = k;
|
||||
nint num3 = num2;
|
||||
num = (array[num2] = (byte)(x[num3] ^ S[num])) & 0xFF;
|
||||
}
|
||||
num = (num + j) % 256;
|
||||
}
|
||||
}
|
||||
|
||||
public IMemoable Copy()
|
||||
{
|
||||
return new MD2Digest(this);
|
||||
}
|
||||
|
||||
public void Reset(IMemoable other)
|
||||
{
|
||||
MD2Digest t = (MD2Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class MD4Digest : GeneralDigest
|
||||
{
|
||||
private const int DigestLength = 16;
|
||||
|
||||
private const int S11 = 3;
|
||||
|
||||
private const int S12 = 7;
|
||||
|
||||
private const int S13 = 11;
|
||||
|
||||
private const int S14 = 19;
|
||||
|
||||
private const int S21 = 3;
|
||||
|
||||
private const int S22 = 5;
|
||||
|
||||
private const int S23 = 9;
|
||||
|
||||
private const int S24 = 13;
|
||||
|
||||
private const int S31 = 3;
|
||||
|
||||
private const int S32 = 9;
|
||||
|
||||
private const int S33 = 11;
|
||||
|
||||
private const int S34 = 15;
|
||||
|
||||
private int H1;
|
||||
|
||||
private int H2;
|
||||
|
||||
private int H3;
|
||||
|
||||
private int H4;
|
||||
|
||||
private int[] X = new int[16];
|
||||
|
||||
private int xOff;
|
||||
|
||||
public override string AlgorithmName => "MD4";
|
||||
|
||||
public MD4Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public MD4Digest(MD4Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(MD4Digest t)
|
||||
{
|
||||
CopyIn((GeneralDigest)t);
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
H4 = t.H4;
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
X[xOff++] = (input[inOff] & 0xFF) | ((input[inOff + 1] & 0xFF) << 8) | ((input[inOff + 2] & 0xFF) << 16) | ((input[inOff + 3] & 0xFF) << 24);
|
||||
if (xOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
X[14] = (int)(bitLength & 0xFFFFFFFFu);
|
||||
X[15] = (int)(bitLength >>> 32);
|
||||
}
|
||||
|
||||
private void UnpackWord(int word, byte[] outBytes, int outOff)
|
||||
{
|
||||
outBytes[outOff] = (byte)word;
|
||||
outBytes[outOff + 1] = (byte)((uint)word >> 8);
|
||||
outBytes[outOff + 2] = (byte)((uint)word >> 16);
|
||||
outBytes[outOff + 3] = (byte)((uint)word >> 24);
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
UnpackWord(H1, output, outOff);
|
||||
UnpackWord(H2, output, outOff + 4);
|
||||
UnpackWord(H3, output, outOff + 8);
|
||||
UnpackWord(H4, output, outOff + 12);
|
||||
Reset();
|
||||
return 16;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H1 = 1732584193;
|
||||
H2 = -271733879;
|
||||
H3 = -1732584194;
|
||||
H4 = 271733878;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int RotateLeft(int x, int n)
|
||||
{
|
||||
return (x << n) | (x >>> 32 - n);
|
||||
}
|
||||
|
||||
private int F(int u, int v, int w)
|
||||
{
|
||||
return (u & v) | (~u & w);
|
||||
}
|
||||
|
||||
private int G(int u, int v, int w)
|
||||
{
|
||||
return (u & v) | (u & w) | (v & w);
|
||||
}
|
||||
|
||||
private int H(int u, int v, int w)
|
||||
{
|
||||
return u ^ v ^ w;
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
int h = H1;
|
||||
int h2 = H2;
|
||||
int h3 = H3;
|
||||
int h4 = H4;
|
||||
h = RotateLeft(h + F(h2, h3, h4) + X[0], 3);
|
||||
h4 = RotateLeft(h4 + F(h, h2, h3) + X[1], 7);
|
||||
h3 = RotateLeft(h3 + F(h4, h, h2) + X[2], 11);
|
||||
h2 = RotateLeft(h2 + F(h3, h4, h) + X[3], 19);
|
||||
h = RotateLeft(h + F(h2, h3, h4) + X[4], 3);
|
||||
h4 = RotateLeft(h4 + F(h, h2, h3) + X[5], 7);
|
||||
h3 = RotateLeft(h3 + F(h4, h, h2) + X[6], 11);
|
||||
h2 = RotateLeft(h2 + F(h3, h4, h) + X[7], 19);
|
||||
h = RotateLeft(h + F(h2, h3, h4) + X[8], 3);
|
||||
h4 = RotateLeft(h4 + F(h, h2, h3) + X[9], 7);
|
||||
h3 = RotateLeft(h3 + F(h4, h, h2) + X[10], 11);
|
||||
h2 = RotateLeft(h2 + F(h3, h4, h) + X[11], 19);
|
||||
h = RotateLeft(h + F(h2, h3, h4) + X[12], 3);
|
||||
h4 = RotateLeft(h4 + F(h, h2, h3) + X[13], 7);
|
||||
h3 = RotateLeft(h3 + F(h4, h, h2) + X[14], 11);
|
||||
h2 = RotateLeft(h2 + F(h3, h4, h) + X[15], 19);
|
||||
h = RotateLeft(h + G(h2, h3, h4) + X[0] + 1518500249, 3);
|
||||
h4 = RotateLeft(h4 + G(h, h2, h3) + X[4] + 1518500249, 5);
|
||||
h3 = RotateLeft(h3 + G(h4, h, h2) + X[8] + 1518500249, 9);
|
||||
h2 = RotateLeft(h2 + G(h3, h4, h) + X[12] + 1518500249, 13);
|
||||
h = RotateLeft(h + G(h2, h3, h4) + X[1] + 1518500249, 3);
|
||||
h4 = RotateLeft(h4 + G(h, h2, h3) + X[5] + 1518500249, 5);
|
||||
h3 = RotateLeft(h3 + G(h4, h, h2) + X[9] + 1518500249, 9);
|
||||
h2 = RotateLeft(h2 + G(h3, h4, h) + X[13] + 1518500249, 13);
|
||||
h = RotateLeft(h + G(h2, h3, h4) + X[2] + 1518500249, 3);
|
||||
h4 = RotateLeft(h4 + G(h, h2, h3) + X[6] + 1518500249, 5);
|
||||
h3 = RotateLeft(h3 + G(h4, h, h2) + X[10] + 1518500249, 9);
|
||||
h2 = RotateLeft(h2 + G(h3, h4, h) + X[14] + 1518500249, 13);
|
||||
h = RotateLeft(h + G(h2, h3, h4) + X[3] + 1518500249, 3);
|
||||
h4 = RotateLeft(h4 + G(h, h2, h3) + X[7] + 1518500249, 5);
|
||||
h3 = RotateLeft(h3 + G(h4, h, h2) + X[11] + 1518500249, 9);
|
||||
h2 = RotateLeft(h2 + G(h3, h4, h) + X[15] + 1518500249, 13);
|
||||
h = RotateLeft(h + H(h2, h3, h4) + X[0] + 1859775393, 3);
|
||||
h4 = RotateLeft(h4 + H(h, h2, h3) + X[8] + 1859775393, 9);
|
||||
h3 = RotateLeft(h3 + H(h4, h, h2) + X[4] + 1859775393, 11);
|
||||
h2 = RotateLeft(h2 + H(h3, h4, h) + X[12] + 1859775393, 15);
|
||||
h = RotateLeft(h + H(h2, h3, h4) + X[2] + 1859775393, 3);
|
||||
h4 = RotateLeft(h4 + H(h, h2, h3) + X[10] + 1859775393, 9);
|
||||
h3 = RotateLeft(h3 + H(h4, h, h2) + X[6] + 1859775393, 11);
|
||||
h2 = RotateLeft(h2 + H(h3, h4, h) + X[14] + 1859775393, 15);
|
||||
h = RotateLeft(h + H(h2, h3, h4) + X[1] + 1859775393, 3);
|
||||
h4 = RotateLeft(h4 + H(h, h2, h3) + X[9] + 1859775393, 9);
|
||||
h3 = RotateLeft(h3 + H(h4, h, h2) + X[5] + 1859775393, 11);
|
||||
h2 = RotateLeft(h2 + H(h3, h4, h) + X[13] + 1859775393, 15);
|
||||
h = RotateLeft(h + H(h2, h3, h4) + X[3] + 1859775393, 3);
|
||||
h4 = RotateLeft(h4 + H(h, h2, h3) + X[11] + 1859775393, 9);
|
||||
h3 = RotateLeft(h3 + H(h4, h, h2) + X[7] + 1859775393, 11);
|
||||
h2 = RotateLeft(h2 + H(h3, h4, h) + X[15] + 1859775393, 15);
|
||||
H1 += h;
|
||||
H2 += h2;
|
||||
H3 += h3;
|
||||
H4 += h4;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new MD4Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
MD4Digest t = (MD4Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class MD5Digest : GeneralDigest
|
||||
{
|
||||
private const int DigestLength = 16;
|
||||
|
||||
private uint H1;
|
||||
|
||||
private uint H2;
|
||||
|
||||
private uint H3;
|
||||
|
||||
private uint H4;
|
||||
|
||||
private uint[] X = new uint[16];
|
||||
|
||||
private int xOff;
|
||||
|
||||
private static readonly int S11 = 7;
|
||||
|
||||
private static readonly int S12 = 12;
|
||||
|
||||
private static readonly int S13 = 17;
|
||||
|
||||
private static readonly int S14 = 22;
|
||||
|
||||
private static readonly int S21 = 5;
|
||||
|
||||
private static readonly int S22 = 9;
|
||||
|
||||
private static readonly int S23 = 14;
|
||||
|
||||
private static readonly int S24 = 20;
|
||||
|
||||
private static readonly int S31 = 4;
|
||||
|
||||
private static readonly int S32 = 11;
|
||||
|
||||
private static readonly int S33 = 16;
|
||||
|
||||
private static readonly int S34 = 23;
|
||||
|
||||
private static readonly int S41 = 6;
|
||||
|
||||
private static readonly int S42 = 10;
|
||||
|
||||
private static readonly int S43 = 15;
|
||||
|
||||
private static readonly int S44 = 21;
|
||||
|
||||
public override string AlgorithmName => "MD5";
|
||||
|
||||
public MD5Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public MD5Digest(MD5Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(MD5Digest t)
|
||||
{
|
||||
CopyIn((GeneralDigest)t);
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
H4 = t.H4;
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
X[xOff] = Pack.LE_To_UInt32(input, inOff);
|
||||
if (++xOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
if (xOff == 15)
|
||||
{
|
||||
X[15] = 0u;
|
||||
}
|
||||
ProcessBlock();
|
||||
}
|
||||
for (int i = xOff; i < 14; i++)
|
||||
{
|
||||
X[i] = 0u;
|
||||
}
|
||||
X[14] = (uint)bitLength;
|
||||
X[15] = (uint)((ulong)bitLength >> 32);
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
Pack.UInt32_To_LE(H1, output, outOff);
|
||||
Pack.UInt32_To_LE(H2, output, outOff + 4);
|
||||
Pack.UInt32_To_LE(H3, output, outOff + 8);
|
||||
Pack.UInt32_To_LE(H4, output, outOff + 12);
|
||||
Reset();
|
||||
return 16;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H1 = 1732584193u;
|
||||
H2 = 4023233417u;
|
||||
H3 = 2562383102u;
|
||||
H4 = 271733878u;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
private static uint RotateLeft(uint x, int n)
|
||||
{
|
||||
return (x << n) | (x >> 32 - n);
|
||||
}
|
||||
|
||||
private static uint F(uint u, uint v, uint w)
|
||||
{
|
||||
return (u & v) | (~u & w);
|
||||
}
|
||||
|
||||
private static uint G(uint u, uint v, uint w)
|
||||
{
|
||||
return (u & w) | (v & ~w);
|
||||
}
|
||||
|
||||
private static uint H(uint u, uint v, uint w)
|
||||
{
|
||||
return u ^ v ^ w;
|
||||
}
|
||||
|
||||
private static uint K(uint u, uint v, uint w)
|
||||
{
|
||||
return v ^ (u | ~w);
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
uint h = H1;
|
||||
uint h2 = H2;
|
||||
uint h3 = H3;
|
||||
uint h4 = H4;
|
||||
h = RotateLeft(h + F(h2, h3, h4) + X[0] + 3614090360u, S11) + h2;
|
||||
h4 = RotateLeft(h4 + F(h, h2, h3) + X[1] + 3905402710u, S12) + h;
|
||||
h3 = RotateLeft(h3 + F(h4, h, h2) + X[2] + 606105819, S13) + h4;
|
||||
h2 = RotateLeft(h2 + F(h3, h4, h) + X[3] + 3250441966u, S14) + h3;
|
||||
h = RotateLeft(h + F(h2, h3, h4) + X[4] + 4118548399u, S11) + h2;
|
||||
h4 = RotateLeft(h4 + F(h, h2, h3) + X[5] + 1200080426, S12) + h;
|
||||
h3 = RotateLeft(h3 + F(h4, h, h2) + X[6] + 2821735955u, S13) + h4;
|
||||
h2 = RotateLeft(h2 + F(h3, h4, h) + X[7] + 4249261313u, S14) + h3;
|
||||
h = RotateLeft(h + F(h2, h3, h4) + X[8] + 1770035416, S11) + h2;
|
||||
h4 = RotateLeft(h4 + F(h, h2, h3) + X[9] + 2336552879u, S12) + h;
|
||||
h3 = RotateLeft(h3 + F(h4, h, h2) + X[10] + 4294925233u, S13) + h4;
|
||||
h2 = RotateLeft(h2 + F(h3, h4, h) + X[11] + 2304563134u, S14) + h3;
|
||||
h = RotateLeft(h + F(h2, h3, h4) + X[12] + 1804603682, S11) + h2;
|
||||
h4 = RotateLeft(h4 + F(h, h2, h3) + X[13] + 4254626195u, S12) + h;
|
||||
h3 = RotateLeft(h3 + F(h4, h, h2) + X[14] + 2792965006u, S13) + h4;
|
||||
h2 = RotateLeft(h2 + F(h3, h4, h) + X[15] + 1236535329, S14) + h3;
|
||||
h = RotateLeft(h + G(h2, h3, h4) + X[1] + 4129170786u, S21) + h2;
|
||||
h4 = RotateLeft(h4 + G(h, h2, h3) + X[6] + 3225465664u, S22) + h;
|
||||
h3 = RotateLeft(h3 + G(h4, h, h2) + X[11] + 643717713, S23) + h4;
|
||||
h2 = RotateLeft(h2 + G(h3, h4, h) + X[0] + 3921069994u, S24) + h3;
|
||||
h = RotateLeft(h + G(h2, h3, h4) + X[5] + 3593408605u, S21) + h2;
|
||||
h4 = RotateLeft(h4 + G(h, h2, h3) + X[10] + 38016083, S22) + h;
|
||||
h3 = RotateLeft(h3 + G(h4, h, h2) + X[15] + 3634488961u, S23) + h4;
|
||||
h2 = RotateLeft(h2 + G(h3, h4, h) + X[4] + 3889429448u, S24) + h3;
|
||||
h = RotateLeft(h + G(h2, h3, h4) + X[9] + 568446438, S21) + h2;
|
||||
h4 = RotateLeft(h4 + G(h, h2, h3) + X[14] + 3275163606u, S22) + h;
|
||||
h3 = RotateLeft(h3 + G(h4, h, h2) + X[3] + 4107603335u, S23) + h4;
|
||||
h2 = RotateLeft(h2 + G(h3, h4, h) + X[8] + 1163531501, S24) + h3;
|
||||
h = RotateLeft(h + G(h2, h3, h4) + X[13] + 2850285829u, S21) + h2;
|
||||
h4 = RotateLeft(h4 + G(h, h2, h3) + X[2] + 4243563512u, S22) + h;
|
||||
h3 = RotateLeft(h3 + G(h4, h, h2) + X[7] + 1735328473, S23) + h4;
|
||||
h2 = RotateLeft(h2 + G(h3, h4, h) + X[12] + 2368359562u, S24) + h3;
|
||||
h = RotateLeft(h + H(h2, h3, h4) + X[5] + 4294588738u, S31) + h2;
|
||||
h4 = RotateLeft(h4 + H(h, h2, h3) + X[8] + 2272392833u, S32) + h;
|
||||
h3 = RotateLeft(h3 + H(h4, h, h2) + X[11] + 1839030562, S33) + h4;
|
||||
h2 = RotateLeft(h2 + H(h3, h4, h) + X[14] + 4259657740u, S34) + h3;
|
||||
h = RotateLeft(h + H(h2, h3, h4) + X[1] + 2763975236u, S31) + h2;
|
||||
h4 = RotateLeft(h4 + H(h, h2, h3) + X[4] + 1272893353, S32) + h;
|
||||
h3 = RotateLeft(h3 + H(h4, h, h2) + X[7] + 4139469664u, S33) + h4;
|
||||
h2 = RotateLeft(h2 + H(h3, h4, h) + X[10] + 3200236656u, S34) + h3;
|
||||
h = RotateLeft(h + H(h2, h3, h4) + X[13] + 681279174, S31) + h2;
|
||||
h4 = RotateLeft(h4 + H(h, h2, h3) + X[0] + 3936430074u, S32) + h;
|
||||
h3 = RotateLeft(h3 + H(h4, h, h2) + X[3] + 3572445317u, S33) + h4;
|
||||
h2 = RotateLeft(h2 + H(h3, h4, h) + X[6] + 76029189, S34) + h3;
|
||||
h = RotateLeft(h + H(h2, h3, h4) + X[9] + 3654602809u, S31) + h2;
|
||||
h4 = RotateLeft(h4 + H(h, h2, h3) + X[12] + 3873151461u, S32) + h;
|
||||
h3 = RotateLeft(h3 + H(h4, h, h2) + X[15] + 530742520, S33) + h4;
|
||||
h2 = RotateLeft(h2 + H(h3, h4, h) + X[2] + 3299628645u, S34) + h3;
|
||||
h = RotateLeft(h + K(h2, h3, h4) + X[0] + 4096336452u, S41) + h2;
|
||||
h4 = RotateLeft(h4 + K(h, h2, h3) + X[7] + 1126891415, S42) + h;
|
||||
h3 = RotateLeft(h3 + K(h4, h, h2) + X[14] + 2878612391u, S43) + h4;
|
||||
h2 = RotateLeft(h2 + K(h3, h4, h) + X[5] + 4237533241u, S44) + h3;
|
||||
h = RotateLeft(h + K(h2, h3, h4) + X[12] + 1700485571, S41) + h2;
|
||||
h4 = RotateLeft(h4 + K(h, h2, h3) + X[3] + 2399980690u, S42) + h;
|
||||
h3 = RotateLeft(h3 + K(h4, h, h2) + X[10] + 4293915773u, S43) + h4;
|
||||
h2 = RotateLeft(h2 + K(h3, h4, h) + X[1] + 2240044497u, S44) + h3;
|
||||
h = RotateLeft(h + K(h2, h3, h4) + X[8] + 1873313359, S41) + h2;
|
||||
h4 = RotateLeft(h4 + K(h, h2, h3) + X[15] + 4264355552u, S42) + h;
|
||||
h3 = RotateLeft(h3 + K(h4, h, h2) + X[6] + 2734768916u, S43) + h4;
|
||||
h2 = RotateLeft(h2 + K(h3, h4, h) + X[13] + 1309151649, S44) + h3;
|
||||
h = RotateLeft(h + K(h2, h3, h4) + X[4] + 4149444226u, S41) + h2;
|
||||
h4 = RotateLeft(h4 + K(h, h2, h3) + X[11] + 3174756917u, S42) + h;
|
||||
h3 = RotateLeft(h3 + K(h4, h, h2) + X[2] + 718787259, S43) + h4;
|
||||
h2 = RotateLeft(h2 + K(h3, h4, h) + X[9] + 3951481745u, S44) + h3;
|
||||
H1 += h;
|
||||
H2 += h2;
|
||||
H3 += h3;
|
||||
H4 += h4;
|
||||
xOff = 0;
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new MD5Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
MD5Digest t = (MD5Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class NonMemoableDigest : IDigest
|
||||
{
|
||||
protected readonly IDigest mBaseDigest;
|
||||
|
||||
public virtual string AlgorithmName => mBaseDigest.AlgorithmName;
|
||||
|
||||
public NonMemoableDigest(IDigest baseDigest)
|
||||
{
|
||||
if (baseDigest == null)
|
||||
{
|
||||
throw new ArgumentNullException("baseDigest");
|
||||
}
|
||||
mBaseDigest = baseDigest;
|
||||
}
|
||||
|
||||
public virtual int GetDigestSize()
|
||||
{
|
||||
return mBaseDigest.GetDigestSize();
|
||||
}
|
||||
|
||||
public virtual void Update(byte input)
|
||||
{
|
||||
mBaseDigest.Update(input);
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] input, int inOff, int len)
|
||||
{
|
||||
mBaseDigest.BlockUpdate(input, inOff, len);
|
||||
}
|
||||
|
||||
public virtual int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
return mBaseDigest.DoFinal(output, outOff);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
mBaseDigest.Reset();
|
||||
}
|
||||
|
||||
public virtual int GetByteLength()
|
||||
{
|
||||
return mBaseDigest.GetByteLength();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class NullDigest : IDigest
|
||||
{
|
||||
private readonly MemoryStream bOut = new MemoryStream();
|
||||
|
||||
public string AlgorithmName => "NULL";
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int GetDigestSize()
|
||||
{
|
||||
return (int)bOut.Length;
|
||||
}
|
||||
|
||||
public void Update(byte b)
|
||||
{
|
||||
bOut.WriteByte(b);
|
||||
}
|
||||
|
||||
public void BlockUpdate(byte[] inBytes, int inOff, int len)
|
||||
{
|
||||
bOut.Write(inBytes, inOff, len);
|
||||
}
|
||||
|
||||
public int DoFinal(byte[] outBytes, int outOff)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Streams.WriteBufTo(bOut, outBytes, outOff);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
bOut.SetLength(0L);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class RipeMD128Digest : GeneralDigest
|
||||
{
|
||||
private const int DigestLength = 16;
|
||||
|
||||
private int H0;
|
||||
|
||||
private int H1;
|
||||
|
||||
private int H2;
|
||||
|
||||
private int H3;
|
||||
|
||||
private int[] X = new int[16];
|
||||
|
||||
private int xOff;
|
||||
|
||||
public override string AlgorithmName => "RIPEMD128";
|
||||
|
||||
public RipeMD128Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public RipeMD128Digest(RipeMD128Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(RipeMD128Digest t)
|
||||
{
|
||||
CopyIn((GeneralDigest)t);
|
||||
H0 = t.H0;
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
X[xOff++] = (input[inOff] & 0xFF) | ((input[inOff + 1] & 0xFF) << 8) | ((input[inOff + 2] & 0xFF) << 16) | ((input[inOff + 3] & 0xFF) << 24);
|
||||
if (xOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
X[14] = (int)(bitLength & 0xFFFFFFFFu);
|
||||
X[15] = (int)(bitLength >>> 32);
|
||||
}
|
||||
|
||||
private void UnpackWord(int word, byte[] outBytes, int outOff)
|
||||
{
|
||||
outBytes[outOff] = (byte)word;
|
||||
outBytes[outOff + 1] = (byte)((uint)word >> 8);
|
||||
outBytes[outOff + 2] = (byte)((uint)word >> 16);
|
||||
outBytes[outOff + 3] = (byte)((uint)word >> 24);
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
UnpackWord(H0, output, outOff);
|
||||
UnpackWord(H1, output, outOff + 4);
|
||||
UnpackWord(H2, output, outOff + 8);
|
||||
UnpackWord(H3, output, outOff + 12);
|
||||
Reset();
|
||||
return 16;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H0 = 1732584193;
|
||||
H1 = -271733879;
|
||||
H2 = -1732584194;
|
||||
H3 = 271733878;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int RL(int x, int n)
|
||||
{
|
||||
return (x << n) | (x >>> 32 - n);
|
||||
}
|
||||
|
||||
private int F1(int x, int y, int z)
|
||||
{
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
private int F2(int x, int y, int z)
|
||||
{
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
|
||||
private int F3(int x, int y, int z)
|
||||
{
|
||||
return (x | ~y) ^ z;
|
||||
}
|
||||
|
||||
private int F4(int x, int y, int z)
|
||||
{
|
||||
return (x & z) | (y & ~z);
|
||||
}
|
||||
|
||||
private int F1(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F1(b, c, d) + x, s);
|
||||
}
|
||||
|
||||
private int F2(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F2(b, c, d) + x + 1518500249, s);
|
||||
}
|
||||
|
||||
private int F3(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F3(b, c, d) + x + 1859775393, s);
|
||||
}
|
||||
|
||||
private int F4(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F4(b, c, d) + x + -1894007588, s);
|
||||
}
|
||||
|
||||
private int FF1(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F1(b, c, d) + x, s);
|
||||
}
|
||||
|
||||
private int FF2(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F2(b, c, d) + x + 1836072691, s);
|
||||
}
|
||||
|
||||
private int FF3(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F3(b, c, d) + x + 1548603684, s);
|
||||
}
|
||||
|
||||
private int FF4(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F4(b, c, d) + x + 1352829926, s);
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
int h;
|
||||
int a = (h = H0);
|
||||
int h2;
|
||||
int num = (h2 = H1);
|
||||
int h3;
|
||||
int num2 = (h3 = H2);
|
||||
int h4;
|
||||
int num3 = (h4 = H3);
|
||||
a = F1(a, num, num2, num3, X[0], 11);
|
||||
num3 = F1(num3, a, num, num2, X[1], 14);
|
||||
num2 = F1(num2, num3, a, num, X[2], 15);
|
||||
num = F1(num, num2, num3, a, X[3], 12);
|
||||
a = F1(a, num, num2, num3, X[4], 5);
|
||||
num3 = F1(num3, a, num, num2, X[5], 8);
|
||||
num2 = F1(num2, num3, a, num, X[6], 7);
|
||||
num = F1(num, num2, num3, a, X[7], 9);
|
||||
a = F1(a, num, num2, num3, X[8], 11);
|
||||
num3 = F1(num3, a, num, num2, X[9], 13);
|
||||
num2 = F1(num2, num3, a, num, X[10], 14);
|
||||
num = F1(num, num2, num3, a, X[11], 15);
|
||||
a = F1(a, num, num2, num3, X[12], 6);
|
||||
num3 = F1(num3, a, num, num2, X[13], 7);
|
||||
num2 = F1(num2, num3, a, num, X[14], 9);
|
||||
num = F1(num, num2, num3, a, X[15], 8);
|
||||
a = F2(a, num, num2, num3, X[7], 7);
|
||||
num3 = F2(num3, a, num, num2, X[4], 6);
|
||||
num2 = F2(num2, num3, a, num, X[13], 8);
|
||||
num = F2(num, num2, num3, a, X[1], 13);
|
||||
a = F2(a, num, num2, num3, X[10], 11);
|
||||
num3 = F2(num3, a, num, num2, X[6], 9);
|
||||
num2 = F2(num2, num3, a, num, X[15], 7);
|
||||
num = F2(num, num2, num3, a, X[3], 15);
|
||||
a = F2(a, num, num2, num3, X[12], 7);
|
||||
num3 = F2(num3, a, num, num2, X[0], 12);
|
||||
num2 = F2(num2, num3, a, num, X[9], 15);
|
||||
num = F2(num, num2, num3, a, X[5], 9);
|
||||
a = F2(a, num, num2, num3, X[2], 11);
|
||||
num3 = F2(num3, a, num, num2, X[14], 7);
|
||||
num2 = F2(num2, num3, a, num, X[11], 13);
|
||||
num = F2(num, num2, num3, a, X[8], 12);
|
||||
a = F3(a, num, num2, num3, X[3], 11);
|
||||
num3 = F3(num3, a, num, num2, X[10], 13);
|
||||
num2 = F3(num2, num3, a, num, X[14], 6);
|
||||
num = F3(num, num2, num3, a, X[4], 7);
|
||||
a = F3(a, num, num2, num3, X[9], 14);
|
||||
num3 = F3(num3, a, num, num2, X[15], 9);
|
||||
num2 = F3(num2, num3, a, num, X[8], 13);
|
||||
num = F3(num, num2, num3, a, X[1], 15);
|
||||
a = F3(a, num, num2, num3, X[2], 14);
|
||||
num3 = F3(num3, a, num, num2, X[7], 8);
|
||||
num2 = F3(num2, num3, a, num, X[0], 13);
|
||||
num = F3(num, num2, num3, a, X[6], 6);
|
||||
a = F3(a, num, num2, num3, X[13], 5);
|
||||
num3 = F3(num3, a, num, num2, X[11], 12);
|
||||
num2 = F3(num2, num3, a, num, X[5], 7);
|
||||
num = F3(num, num2, num3, a, X[12], 5);
|
||||
a = F4(a, num, num2, num3, X[1], 11);
|
||||
num3 = F4(num3, a, num, num2, X[9], 12);
|
||||
num2 = F4(num2, num3, a, num, X[11], 14);
|
||||
num = F4(num, num2, num3, a, X[10], 15);
|
||||
a = F4(a, num, num2, num3, X[0], 14);
|
||||
num3 = F4(num3, a, num, num2, X[8], 15);
|
||||
num2 = F4(num2, num3, a, num, X[12], 9);
|
||||
num = F4(num, num2, num3, a, X[4], 8);
|
||||
a = F4(a, num, num2, num3, X[13], 9);
|
||||
num3 = F4(num3, a, num, num2, X[3], 14);
|
||||
num2 = F4(num2, num3, a, num, X[7], 5);
|
||||
num = F4(num, num2, num3, a, X[15], 6);
|
||||
a = F4(a, num, num2, num3, X[14], 8);
|
||||
num3 = F4(num3, a, num, num2, X[5], 6);
|
||||
num2 = F4(num2, num3, a, num, X[6], 5);
|
||||
num = F4(num, num2, num3, a, X[2], 12);
|
||||
h = FF4(h, h2, h3, h4, X[5], 8);
|
||||
h4 = FF4(h4, h, h2, h3, X[14], 9);
|
||||
h3 = FF4(h3, h4, h, h2, X[7], 9);
|
||||
h2 = FF4(h2, h3, h4, h, X[0], 11);
|
||||
h = FF4(h, h2, h3, h4, X[9], 13);
|
||||
h4 = FF4(h4, h, h2, h3, X[2], 15);
|
||||
h3 = FF4(h3, h4, h, h2, X[11], 15);
|
||||
h2 = FF4(h2, h3, h4, h, X[4], 5);
|
||||
h = FF4(h, h2, h3, h4, X[13], 7);
|
||||
h4 = FF4(h4, h, h2, h3, X[6], 7);
|
||||
h3 = FF4(h3, h4, h, h2, X[15], 8);
|
||||
h2 = FF4(h2, h3, h4, h, X[8], 11);
|
||||
h = FF4(h, h2, h3, h4, X[1], 14);
|
||||
h4 = FF4(h4, h, h2, h3, X[10], 14);
|
||||
h3 = FF4(h3, h4, h, h2, X[3], 12);
|
||||
h2 = FF4(h2, h3, h4, h, X[12], 6);
|
||||
h = FF3(h, h2, h3, h4, X[6], 9);
|
||||
h4 = FF3(h4, h, h2, h3, X[11], 13);
|
||||
h3 = FF3(h3, h4, h, h2, X[3], 15);
|
||||
h2 = FF3(h2, h3, h4, h, X[7], 7);
|
||||
h = FF3(h, h2, h3, h4, X[0], 12);
|
||||
h4 = FF3(h4, h, h2, h3, X[13], 8);
|
||||
h3 = FF3(h3, h4, h, h2, X[5], 9);
|
||||
h2 = FF3(h2, h3, h4, h, X[10], 11);
|
||||
h = FF3(h, h2, h3, h4, X[14], 7);
|
||||
h4 = FF3(h4, h, h2, h3, X[15], 7);
|
||||
h3 = FF3(h3, h4, h, h2, X[8], 12);
|
||||
h2 = FF3(h2, h3, h4, h, X[12], 7);
|
||||
h = FF3(h, h2, h3, h4, X[4], 6);
|
||||
h4 = FF3(h4, h, h2, h3, X[9], 15);
|
||||
h3 = FF3(h3, h4, h, h2, X[1], 13);
|
||||
h2 = FF3(h2, h3, h4, h, X[2], 11);
|
||||
h = FF2(h, h2, h3, h4, X[15], 9);
|
||||
h4 = FF2(h4, h, h2, h3, X[5], 7);
|
||||
h3 = FF2(h3, h4, h, h2, X[1], 15);
|
||||
h2 = FF2(h2, h3, h4, h, X[3], 11);
|
||||
h = FF2(h, h2, h3, h4, X[7], 8);
|
||||
h4 = FF2(h4, h, h2, h3, X[14], 6);
|
||||
h3 = FF2(h3, h4, h, h2, X[6], 6);
|
||||
h2 = FF2(h2, h3, h4, h, X[9], 14);
|
||||
h = FF2(h, h2, h3, h4, X[11], 12);
|
||||
h4 = FF2(h4, h, h2, h3, X[8], 13);
|
||||
h3 = FF2(h3, h4, h, h2, X[12], 5);
|
||||
h2 = FF2(h2, h3, h4, h, X[2], 14);
|
||||
h = FF2(h, h2, h3, h4, X[10], 13);
|
||||
h4 = FF2(h4, h, h2, h3, X[0], 13);
|
||||
h3 = FF2(h3, h4, h, h2, X[4], 7);
|
||||
h2 = FF2(h2, h3, h4, h, X[13], 5);
|
||||
h = FF1(h, h2, h3, h4, X[8], 15);
|
||||
h4 = FF1(h4, h, h2, h3, X[6], 5);
|
||||
h3 = FF1(h3, h4, h, h2, X[4], 8);
|
||||
h2 = FF1(h2, h3, h4, h, X[1], 11);
|
||||
h = FF1(h, h2, h3, h4, X[3], 14);
|
||||
h4 = FF1(h4, h, h2, h3, X[11], 14);
|
||||
h3 = FF1(h3, h4, h, h2, X[15], 6);
|
||||
h2 = FF1(h2, h3, h4, h, X[0], 14);
|
||||
h = FF1(h, h2, h3, h4, X[5], 6);
|
||||
h4 = FF1(h4, h, h2, h3, X[12], 9);
|
||||
h3 = FF1(h3, h4, h, h2, X[2], 12);
|
||||
h2 = FF1(h2, h3, h4, h, X[13], 9);
|
||||
h = FF1(h, h2, h3, h4, X[9], 12);
|
||||
h4 = FF1(h4, h, h2, h3, X[7], 5);
|
||||
h3 = FF1(h3, h4, h, h2, X[10], 15);
|
||||
h2 = FF1(h2, h3, h4, h, X[14], 8);
|
||||
h4 += num2 + H1;
|
||||
H1 = H2 + num3 + h;
|
||||
H2 = H3 + a + h2;
|
||||
H3 = H0 + num + h3;
|
||||
H0 = h4;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new RipeMD128Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
RipeMD128Digest t = (RipeMD128Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,493 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class RipeMD160Digest : GeneralDigest
|
||||
{
|
||||
private const int DigestLength = 20;
|
||||
|
||||
private int H0;
|
||||
|
||||
private int H1;
|
||||
|
||||
private int H2;
|
||||
|
||||
private int H3;
|
||||
|
||||
private int H4;
|
||||
|
||||
private int[] X = new int[16];
|
||||
|
||||
private int xOff;
|
||||
|
||||
public override string AlgorithmName => "RIPEMD160";
|
||||
|
||||
public RipeMD160Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public RipeMD160Digest(RipeMD160Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(RipeMD160Digest t)
|
||||
{
|
||||
CopyIn((GeneralDigest)t);
|
||||
H0 = t.H0;
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
H4 = t.H4;
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
X[xOff++] = (input[inOff] & 0xFF) | ((input[inOff + 1] & 0xFF) << 8) | ((input[inOff + 2] & 0xFF) << 16) | ((input[inOff + 3] & 0xFF) << 24);
|
||||
if (xOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
X[14] = (int)(bitLength & 0xFFFFFFFFu);
|
||||
X[15] = (int)(bitLength >>> 32);
|
||||
}
|
||||
|
||||
private void UnpackWord(int word, byte[] outBytes, int outOff)
|
||||
{
|
||||
outBytes[outOff] = (byte)word;
|
||||
outBytes[outOff + 1] = (byte)((uint)word >> 8);
|
||||
outBytes[outOff + 2] = (byte)((uint)word >> 16);
|
||||
outBytes[outOff + 3] = (byte)((uint)word >> 24);
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
UnpackWord(H0, output, outOff);
|
||||
UnpackWord(H1, output, outOff + 4);
|
||||
UnpackWord(H2, output, outOff + 8);
|
||||
UnpackWord(H3, output, outOff + 12);
|
||||
UnpackWord(H4, output, outOff + 16);
|
||||
Reset();
|
||||
return 20;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H0 = 1732584193;
|
||||
H1 = -271733879;
|
||||
H2 = -1732584194;
|
||||
H3 = 271733878;
|
||||
H4 = -1009589776;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int RL(int x, int n)
|
||||
{
|
||||
return (x << n) | (x >>> 32 - n);
|
||||
}
|
||||
|
||||
private int F1(int x, int y, int z)
|
||||
{
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
private int F2(int x, int y, int z)
|
||||
{
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
|
||||
private int F3(int x, int y, int z)
|
||||
{
|
||||
return (x | ~y) ^ z;
|
||||
}
|
||||
|
||||
private int F4(int x, int y, int z)
|
||||
{
|
||||
return (x & z) | (y & ~z);
|
||||
}
|
||||
|
||||
private int F5(int x, int y, int z)
|
||||
{
|
||||
return x ^ (y | ~z);
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
int h;
|
||||
int num = (h = H0);
|
||||
int h2;
|
||||
int num2 = (h2 = H1);
|
||||
int h3;
|
||||
int num3 = (h3 = H2);
|
||||
int h4;
|
||||
int num4 = (h4 = H3);
|
||||
int h5;
|
||||
int num5 = (h5 = H4);
|
||||
num = RL(num + F1(num2, num3, num4) + X[0], 11) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F1(num, num2, num3) + X[1], 14) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F1(num5, num, num2) + X[2], 15) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F1(num4, num5, num) + X[3], 12) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F1(num3, num4, num5) + X[4], 5) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F1(num2, num3, num4) + X[5], 8) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F1(num, num2, num3) + X[6], 7) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F1(num5, num, num2) + X[7], 9) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F1(num4, num5, num) + X[8], 11) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F1(num3, num4, num5) + X[9], 13) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F1(num2, num3, num4) + X[10], 14) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F1(num, num2, num3) + X[11], 15) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F1(num5, num, num2) + X[12], 6) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F1(num4, num5, num) + X[13], 7) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F1(num3, num4, num5) + X[14], 9) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F1(num2, num3, num4) + X[15], 8) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
h = RL(h + F5(h2, h3, h4) + X[5] + 1352829926, 8) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F5(h, h2, h3) + X[14] + 1352829926, 9) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F5(h5, h, h2) + X[7] + 1352829926, 9) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F5(h4, h5, h) + X[0] + 1352829926, 11) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F5(h3, h4, h5) + X[9] + 1352829926, 13) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F5(h2, h3, h4) + X[2] + 1352829926, 15) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F5(h, h2, h3) + X[11] + 1352829926, 15) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F5(h5, h, h2) + X[4] + 1352829926, 5) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F5(h4, h5, h) + X[13] + 1352829926, 7) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F5(h3, h4, h5) + X[6] + 1352829926, 7) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F5(h2, h3, h4) + X[15] + 1352829926, 8) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F5(h, h2, h3) + X[8] + 1352829926, 11) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F5(h5, h, h2) + X[1] + 1352829926, 14) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F5(h4, h5, h) + X[10] + 1352829926, 14) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F5(h3, h4, h5) + X[3] + 1352829926, 12) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F5(h2, h3, h4) + X[12] + 1352829926, 6) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
num5 = RL(num5 + F2(num, num2, num3) + X[7] + 1518500249, 7) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F2(num5, num, num2) + X[4] + 1518500249, 6) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F2(num4, num5, num) + X[13] + 1518500249, 8) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F2(num3, num4, num5) + X[1] + 1518500249, 13) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F2(num2, num3, num4) + X[10] + 1518500249, 11) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F2(num, num2, num3) + X[6] + 1518500249, 9) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F2(num5, num, num2) + X[15] + 1518500249, 7) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F2(num4, num5, num) + X[3] + 1518500249, 15) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F2(num3, num4, num5) + X[12] + 1518500249, 7) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F2(num2, num3, num4) + X[0] + 1518500249, 12) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F2(num, num2, num3) + X[9] + 1518500249, 15) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F2(num5, num, num2) + X[5] + 1518500249, 9) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F2(num4, num5, num) + X[2] + 1518500249, 11) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F2(num3, num4, num5) + X[14] + 1518500249, 7) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F2(num2, num3, num4) + X[11] + 1518500249, 13) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F2(num, num2, num3) + X[8] + 1518500249, 12) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
h5 = RL(h5 + F4(h, h2, h3) + X[6] + 1548603684, 9) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F4(h5, h, h2) + X[11] + 1548603684, 13) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F4(h4, h5, h) + X[3] + 1548603684, 15) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F4(h3, h4, h5) + X[7] + 1548603684, 7) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F4(h2, h3, h4) + X[0] + 1548603684, 12) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F4(h, h2, h3) + X[13] + 1548603684, 8) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F4(h5, h, h2) + X[5] + 1548603684, 9) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F4(h4, h5, h) + X[10] + 1548603684, 11) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F4(h3, h4, h5) + X[14] + 1548603684, 7) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F4(h2, h3, h4) + X[15] + 1548603684, 7) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F4(h, h2, h3) + X[8] + 1548603684, 12) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F4(h5, h, h2) + X[12] + 1548603684, 7) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F4(h4, h5, h) + X[4] + 1548603684, 6) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F4(h3, h4, h5) + X[9] + 1548603684, 15) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F4(h2, h3, h4) + X[1] + 1548603684, 13) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F4(h, h2, h3) + X[2] + 1548603684, 11) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
num4 = RL(num4 + F3(num5, num, num2) + X[3] + 1859775393, 11) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F3(num4, num5, num) + X[10] + 1859775393, 13) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F3(num3, num4, num5) + X[14] + 1859775393, 6) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F3(num2, num3, num4) + X[4] + 1859775393, 7) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F3(num, num2, num3) + X[9] + 1859775393, 14) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F3(num5, num, num2) + X[15] + 1859775393, 9) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F3(num4, num5, num) + X[8] + 1859775393, 13) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F3(num3, num4, num5) + X[1] + 1859775393, 15) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F3(num2, num3, num4) + X[2] + 1859775393, 14) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F3(num, num2, num3) + X[7] + 1859775393, 8) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F3(num5, num, num2) + X[0] + 1859775393, 13) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F3(num4, num5, num) + X[6] + 1859775393, 6) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F3(num3, num4, num5) + X[13] + 1859775393, 5) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F3(num2, num3, num4) + X[11] + 1859775393, 12) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F3(num, num2, num3) + X[5] + 1859775393, 7) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F3(num5, num, num2) + X[12] + 1859775393, 5) + num3;
|
||||
num = RL(num, 10);
|
||||
h4 = RL(h4 + F3(h5, h, h2) + X[15] + 1836072691, 9) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F3(h4, h5, h) + X[5] + 1836072691, 7) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F3(h3, h4, h5) + X[1] + 1836072691, 15) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F3(h2, h3, h4) + X[3] + 1836072691, 11) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F3(h, h2, h3) + X[7] + 1836072691, 8) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F3(h5, h, h2) + X[14] + 1836072691, 6) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F3(h4, h5, h) + X[6] + 1836072691, 6) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F3(h3, h4, h5) + X[9] + 1836072691, 14) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F3(h2, h3, h4) + X[11] + 1836072691, 12) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F3(h, h2, h3) + X[8] + 1836072691, 13) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F3(h5, h, h2) + X[12] + 1836072691, 5) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F3(h4, h5, h) + X[2] + 1836072691, 14) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F3(h3, h4, h5) + X[10] + 1836072691, 13) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F3(h2, h3, h4) + X[0] + 1836072691, 13) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F3(h, h2, h3) + X[4] + 1836072691, 7) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F3(h5, h, h2) + X[13] + 1836072691, 5) + h3;
|
||||
h = RL(h, 10);
|
||||
num3 = RL(num3 + F4(num4, num5, num) + X[1] + -1894007588, 11) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F4(num3, num4, num5) + X[9] + -1894007588, 12) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F4(num2, num3, num4) + X[11] + -1894007588, 14) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F4(num, num2, num3) + X[10] + -1894007588, 15) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F4(num5, num, num2) + X[0] + -1894007588, 14) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F4(num4, num5, num) + X[8] + -1894007588, 15) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F4(num3, num4, num5) + X[12] + -1894007588, 9) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F4(num2, num3, num4) + X[4] + -1894007588, 8) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F4(num, num2, num3) + X[13] + -1894007588, 9) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F4(num5, num, num2) + X[3] + -1894007588, 14) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F4(num4, num5, num) + X[7] + -1894007588, 5) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F4(num3, num4, num5) + X[15] + -1894007588, 6) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F4(num2, num3, num4) + X[14] + -1894007588, 8) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F4(num, num2, num3) + X[5] + -1894007588, 6) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F4(num5, num, num2) + X[6] + -1894007588, 5) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F4(num4, num5, num) + X[2] + -1894007588, 12) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
h3 = RL(h3 + F2(h4, h5, h) + X[8] + 2053994217, 15) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F2(h3, h4, h5) + X[6] + 2053994217, 5) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F2(h2, h3, h4) + X[4] + 2053994217, 8) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F2(h, h2, h3) + X[1] + 2053994217, 11) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F2(h5, h, h2) + X[3] + 2053994217, 14) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F2(h4, h5, h) + X[11] + 2053994217, 14) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F2(h3, h4, h5) + X[15] + 2053994217, 6) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F2(h2, h3, h4) + X[0] + 2053994217, 14) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F2(h, h2, h3) + X[5] + 2053994217, 6) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F2(h5, h, h2) + X[12] + 2053994217, 9) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F2(h4, h5, h) + X[2] + 2053994217, 12) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F2(h3, h4, h5) + X[13] + 2053994217, 9) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F2(h2, h3, h4) + X[9] + 2053994217, 12) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F2(h, h2, h3) + X[7] + 2053994217, 5) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F2(h5, h, h2) + X[10] + 2053994217, 15) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F2(h4, h5, h) + X[14] + 2053994217, 8) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
num2 = RL(num2 + F5(num3, num4, num5) + X[4] + -1454113458, 9) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F5(num2, num3, num4) + X[0] + -1454113458, 15) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F5(num, num2, num3) + X[5] + -1454113458, 5) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F5(num5, num, num2) + X[9] + -1454113458, 11) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F5(num4, num5, num) + X[7] + -1454113458, 6) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F5(num3, num4, num5) + X[12] + -1454113458, 8) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F5(num2, num3, num4) + X[2] + -1454113458, 13) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F5(num, num2, num3) + X[10] + -1454113458, 12) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F5(num5, num, num2) + X[14] + -1454113458, 5) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F5(num4, num5, num) + X[1] + -1454113458, 12) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F5(num3, num4, num5) + X[3] + -1454113458, 13) + num;
|
||||
num4 = RL(num4, 10);
|
||||
num = RL(num + F5(num2, num3, num4) + X[8] + -1454113458, 14) + num5;
|
||||
num3 = RL(num3, 10);
|
||||
num5 = RL(num5 + F5(num, num2, num3) + X[11] + -1454113458, 11) + num4;
|
||||
num2 = RL(num2, 10);
|
||||
num4 = RL(num4 + F5(num5, num, num2) + X[6] + -1454113458, 8) + num3;
|
||||
num = RL(num, 10);
|
||||
num3 = RL(num3 + F5(num4, num5, num) + X[15] + -1454113458, 5) + num2;
|
||||
num5 = RL(num5, 10);
|
||||
num2 = RL(num2 + F5(num3, num4, num5) + X[13] + -1454113458, 6) + num;
|
||||
num4 = RL(num4, 10);
|
||||
h2 = RL(h2 + F1(h3, h4, h5) + X[12], 8) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F1(h2, h3, h4) + X[15], 5) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F1(h, h2, h3) + X[10], 12) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F1(h5, h, h2) + X[4], 9) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F1(h4, h5, h) + X[1], 12) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F1(h3, h4, h5) + X[5], 5) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F1(h2, h3, h4) + X[8], 14) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F1(h, h2, h3) + X[7], 6) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F1(h5, h, h2) + X[6], 8) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F1(h4, h5, h) + X[2], 13) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F1(h3, h4, h5) + X[13], 6) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F1(h2, h3, h4) + X[14], 5) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F1(h, h2, h3) + X[0], 15) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F1(h5, h, h2) + X[3], 13) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F1(h4, h5, h) + X[9], 11) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F1(h3, h4, h5) + X[11], 11) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h4 += num3 + H1;
|
||||
H1 = H2 + num4 + h5;
|
||||
H2 = H3 + num5 + h;
|
||||
H3 = H4 + num + h2;
|
||||
H4 = H0 + num2 + h3;
|
||||
H0 = h4;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new RipeMD160Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
RipeMD160Digest t = (RipeMD160Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class RipeMD256Digest : GeneralDigest
|
||||
{
|
||||
private const int DigestLength = 32;
|
||||
|
||||
private int H0;
|
||||
|
||||
private int H1;
|
||||
|
||||
private int H2;
|
||||
|
||||
private int H3;
|
||||
|
||||
private int H4;
|
||||
|
||||
private int H5;
|
||||
|
||||
private int H6;
|
||||
|
||||
private int H7;
|
||||
|
||||
private int[] X = new int[16];
|
||||
|
||||
private int xOff;
|
||||
|
||||
public override string AlgorithmName => "RIPEMD256";
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
public RipeMD256Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public RipeMD256Digest(RipeMD256Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(RipeMD256Digest t)
|
||||
{
|
||||
CopyIn((GeneralDigest)t);
|
||||
H0 = t.H0;
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
H4 = t.H4;
|
||||
H5 = t.H5;
|
||||
H6 = t.H6;
|
||||
H7 = t.H7;
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
X[xOff++] = (input[inOff] & 0xFF) | ((input[inOff + 1] & 0xFF) << 8) | ((input[inOff + 2] & 0xFF) << 16) | ((input[inOff + 3] & 0xFF) << 24);
|
||||
if (xOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
X[14] = (int)(bitLength & 0xFFFFFFFFu);
|
||||
X[15] = (int)(bitLength >>> 32);
|
||||
}
|
||||
|
||||
private void UnpackWord(int word, byte[] outBytes, int outOff)
|
||||
{
|
||||
outBytes[outOff] = (byte)word;
|
||||
outBytes[outOff + 1] = (byte)((uint)word >> 8);
|
||||
outBytes[outOff + 2] = (byte)((uint)word >> 16);
|
||||
outBytes[outOff + 3] = (byte)((uint)word >> 24);
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
UnpackWord(H0, output, outOff);
|
||||
UnpackWord(H1, output, outOff + 4);
|
||||
UnpackWord(H2, output, outOff + 8);
|
||||
UnpackWord(H3, output, outOff + 12);
|
||||
UnpackWord(H4, output, outOff + 16);
|
||||
UnpackWord(H5, output, outOff + 20);
|
||||
UnpackWord(H6, output, outOff + 24);
|
||||
UnpackWord(H7, output, outOff + 28);
|
||||
Reset();
|
||||
return 32;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H0 = 1732584193;
|
||||
H1 = -271733879;
|
||||
H2 = -1732584194;
|
||||
H3 = 271733878;
|
||||
H4 = 1985229328;
|
||||
H5 = -19088744;
|
||||
H6 = -1985229329;
|
||||
H7 = 19088743;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int RL(int x, int n)
|
||||
{
|
||||
return (x << n) | (x >>> 32 - n);
|
||||
}
|
||||
|
||||
private int F1(int x, int y, int z)
|
||||
{
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
private int F2(int x, int y, int z)
|
||||
{
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
|
||||
private int F3(int x, int y, int z)
|
||||
{
|
||||
return (x | ~y) ^ z;
|
||||
}
|
||||
|
||||
private int F4(int x, int y, int z)
|
||||
{
|
||||
return (x & z) | (y & ~z);
|
||||
}
|
||||
|
||||
private int F1(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F1(b, c, d) + x, s);
|
||||
}
|
||||
|
||||
private int F2(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F2(b, c, d) + x + 1518500249, s);
|
||||
}
|
||||
|
||||
private int F3(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F3(b, c, d) + x + 1859775393, s);
|
||||
}
|
||||
|
||||
private int F4(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F4(b, c, d) + x + -1894007588, s);
|
||||
}
|
||||
|
||||
private int FF1(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F1(b, c, d) + x, s);
|
||||
}
|
||||
|
||||
private int FF2(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F2(b, c, d) + x + 1836072691, s);
|
||||
}
|
||||
|
||||
private int FF3(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F3(b, c, d) + x + 1548603684, s);
|
||||
}
|
||||
|
||||
private int FF4(int a, int b, int c, int d, int x, int s)
|
||||
{
|
||||
return RL(a + F4(b, c, d) + x + 1352829926, s);
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
int h = H0;
|
||||
int h2 = H1;
|
||||
int h3 = H2;
|
||||
int h4 = H3;
|
||||
int h5 = H4;
|
||||
int h6 = H5;
|
||||
int h7 = H6;
|
||||
int h8 = H7;
|
||||
h = F1(h, h2, h3, h4, X[0], 11);
|
||||
h4 = F1(h4, h, h2, h3, X[1], 14);
|
||||
h3 = F1(h3, h4, h, h2, X[2], 15);
|
||||
h2 = F1(h2, h3, h4, h, X[3], 12);
|
||||
h = F1(h, h2, h3, h4, X[4], 5);
|
||||
h4 = F1(h4, h, h2, h3, X[5], 8);
|
||||
h3 = F1(h3, h4, h, h2, X[6], 7);
|
||||
h2 = F1(h2, h3, h4, h, X[7], 9);
|
||||
h = F1(h, h2, h3, h4, X[8], 11);
|
||||
h4 = F1(h4, h, h2, h3, X[9], 13);
|
||||
h3 = F1(h3, h4, h, h2, X[10], 14);
|
||||
h2 = F1(h2, h3, h4, h, X[11], 15);
|
||||
h = F1(h, h2, h3, h4, X[12], 6);
|
||||
h4 = F1(h4, h, h2, h3, X[13], 7);
|
||||
h3 = F1(h3, h4, h, h2, X[14], 9);
|
||||
h2 = F1(h2, h3, h4, h, X[15], 8);
|
||||
h5 = FF4(h5, h6, h7, h8, X[5], 8);
|
||||
h8 = FF4(h8, h5, h6, h7, X[14], 9);
|
||||
h7 = FF4(h7, h8, h5, h6, X[7], 9);
|
||||
h6 = FF4(h6, h7, h8, h5, X[0], 11);
|
||||
h5 = FF4(h5, h6, h7, h8, X[9], 13);
|
||||
h8 = FF4(h8, h5, h6, h7, X[2], 15);
|
||||
h7 = FF4(h7, h8, h5, h6, X[11], 15);
|
||||
h6 = FF4(h6, h7, h8, h5, X[4], 5);
|
||||
h5 = FF4(h5, h6, h7, h8, X[13], 7);
|
||||
h8 = FF4(h8, h5, h6, h7, X[6], 7);
|
||||
h7 = FF4(h7, h8, h5, h6, X[15], 8);
|
||||
h6 = FF4(h6, h7, h8, h5, X[8], 11);
|
||||
h5 = FF4(h5, h6, h7, h8, X[1], 14);
|
||||
h8 = FF4(h8, h5, h6, h7, X[10], 14);
|
||||
h7 = FF4(h7, h8, h5, h6, X[3], 12);
|
||||
h6 = FF4(h6, h7, h8, h5, X[12], 6);
|
||||
int num = h;
|
||||
h = h5;
|
||||
h5 = num;
|
||||
h = F2(h, h2, h3, h4, X[7], 7);
|
||||
h4 = F2(h4, h, h2, h3, X[4], 6);
|
||||
h3 = F2(h3, h4, h, h2, X[13], 8);
|
||||
h2 = F2(h2, h3, h4, h, X[1], 13);
|
||||
h = F2(h, h2, h3, h4, X[10], 11);
|
||||
h4 = F2(h4, h, h2, h3, X[6], 9);
|
||||
h3 = F2(h3, h4, h, h2, X[15], 7);
|
||||
h2 = F2(h2, h3, h4, h, X[3], 15);
|
||||
h = F2(h, h2, h3, h4, X[12], 7);
|
||||
h4 = F2(h4, h, h2, h3, X[0], 12);
|
||||
h3 = F2(h3, h4, h, h2, X[9], 15);
|
||||
h2 = F2(h2, h3, h4, h, X[5], 9);
|
||||
h = F2(h, h2, h3, h4, X[2], 11);
|
||||
h4 = F2(h4, h, h2, h3, X[14], 7);
|
||||
h3 = F2(h3, h4, h, h2, X[11], 13);
|
||||
h2 = F2(h2, h3, h4, h, X[8], 12);
|
||||
h5 = FF3(h5, h6, h7, h8, X[6], 9);
|
||||
h8 = FF3(h8, h5, h6, h7, X[11], 13);
|
||||
h7 = FF3(h7, h8, h5, h6, X[3], 15);
|
||||
h6 = FF3(h6, h7, h8, h5, X[7], 7);
|
||||
h5 = FF3(h5, h6, h7, h8, X[0], 12);
|
||||
h8 = FF3(h8, h5, h6, h7, X[13], 8);
|
||||
h7 = FF3(h7, h8, h5, h6, X[5], 9);
|
||||
h6 = FF3(h6, h7, h8, h5, X[10], 11);
|
||||
h5 = FF3(h5, h6, h7, h8, X[14], 7);
|
||||
h8 = FF3(h8, h5, h6, h7, X[15], 7);
|
||||
h7 = FF3(h7, h8, h5, h6, X[8], 12);
|
||||
h6 = FF3(h6, h7, h8, h5, X[12], 7);
|
||||
h5 = FF3(h5, h6, h7, h8, X[4], 6);
|
||||
h8 = FF3(h8, h5, h6, h7, X[9], 15);
|
||||
h7 = FF3(h7, h8, h5, h6, X[1], 13);
|
||||
h6 = FF3(h6, h7, h8, h5, X[2], 11);
|
||||
num = h2;
|
||||
h2 = h6;
|
||||
h6 = num;
|
||||
h = F3(h, h2, h3, h4, X[3], 11);
|
||||
h4 = F3(h4, h, h2, h3, X[10], 13);
|
||||
h3 = F3(h3, h4, h, h2, X[14], 6);
|
||||
h2 = F3(h2, h3, h4, h, X[4], 7);
|
||||
h = F3(h, h2, h3, h4, X[9], 14);
|
||||
h4 = F3(h4, h, h2, h3, X[15], 9);
|
||||
h3 = F3(h3, h4, h, h2, X[8], 13);
|
||||
h2 = F3(h2, h3, h4, h, X[1], 15);
|
||||
h = F3(h, h2, h3, h4, X[2], 14);
|
||||
h4 = F3(h4, h, h2, h3, X[7], 8);
|
||||
h3 = F3(h3, h4, h, h2, X[0], 13);
|
||||
h2 = F3(h2, h3, h4, h, X[6], 6);
|
||||
h = F3(h, h2, h3, h4, X[13], 5);
|
||||
h4 = F3(h4, h, h2, h3, X[11], 12);
|
||||
h3 = F3(h3, h4, h, h2, X[5], 7);
|
||||
h2 = F3(h2, h3, h4, h, X[12], 5);
|
||||
h5 = FF2(h5, h6, h7, h8, X[15], 9);
|
||||
h8 = FF2(h8, h5, h6, h7, X[5], 7);
|
||||
h7 = FF2(h7, h8, h5, h6, X[1], 15);
|
||||
h6 = FF2(h6, h7, h8, h5, X[3], 11);
|
||||
h5 = FF2(h5, h6, h7, h8, X[7], 8);
|
||||
h8 = FF2(h8, h5, h6, h7, X[14], 6);
|
||||
h7 = FF2(h7, h8, h5, h6, X[6], 6);
|
||||
h6 = FF2(h6, h7, h8, h5, X[9], 14);
|
||||
h5 = FF2(h5, h6, h7, h8, X[11], 12);
|
||||
h8 = FF2(h8, h5, h6, h7, X[8], 13);
|
||||
h7 = FF2(h7, h8, h5, h6, X[12], 5);
|
||||
h6 = FF2(h6, h7, h8, h5, X[2], 14);
|
||||
h5 = FF2(h5, h6, h7, h8, X[10], 13);
|
||||
h8 = FF2(h8, h5, h6, h7, X[0], 13);
|
||||
h7 = FF2(h7, h8, h5, h6, X[4], 7);
|
||||
h6 = FF2(h6, h7, h8, h5, X[13], 5);
|
||||
num = h3;
|
||||
h3 = h7;
|
||||
h7 = num;
|
||||
h = F4(h, h2, h3, h4, X[1], 11);
|
||||
h4 = F4(h4, h, h2, h3, X[9], 12);
|
||||
h3 = F4(h3, h4, h, h2, X[11], 14);
|
||||
h2 = F4(h2, h3, h4, h, X[10], 15);
|
||||
h = F4(h, h2, h3, h4, X[0], 14);
|
||||
h4 = F4(h4, h, h2, h3, X[8], 15);
|
||||
h3 = F4(h3, h4, h, h2, X[12], 9);
|
||||
h2 = F4(h2, h3, h4, h, X[4], 8);
|
||||
h = F4(h, h2, h3, h4, X[13], 9);
|
||||
h4 = F4(h4, h, h2, h3, X[3], 14);
|
||||
h3 = F4(h3, h4, h, h2, X[7], 5);
|
||||
h2 = F4(h2, h3, h4, h, X[15], 6);
|
||||
h = F4(h, h2, h3, h4, X[14], 8);
|
||||
h4 = F4(h4, h, h2, h3, X[5], 6);
|
||||
h3 = F4(h3, h4, h, h2, X[6], 5);
|
||||
h2 = F4(h2, h3, h4, h, X[2], 12);
|
||||
h5 = FF1(h5, h6, h7, h8, X[8], 15);
|
||||
h8 = FF1(h8, h5, h6, h7, X[6], 5);
|
||||
h7 = FF1(h7, h8, h5, h6, X[4], 8);
|
||||
h6 = FF1(h6, h7, h8, h5, X[1], 11);
|
||||
h5 = FF1(h5, h6, h7, h8, X[3], 14);
|
||||
h8 = FF1(h8, h5, h6, h7, X[11], 14);
|
||||
h7 = FF1(h7, h8, h5, h6, X[15], 6);
|
||||
h6 = FF1(h6, h7, h8, h5, X[0], 14);
|
||||
h5 = FF1(h5, h6, h7, h8, X[5], 6);
|
||||
h8 = FF1(h8, h5, h6, h7, X[12], 9);
|
||||
h7 = FF1(h7, h8, h5, h6, X[2], 12);
|
||||
h6 = FF1(h6, h7, h8, h5, X[13], 9);
|
||||
h5 = FF1(h5, h6, h7, h8, X[9], 12);
|
||||
h8 = FF1(h8, h5, h6, h7, X[7], 5);
|
||||
h7 = FF1(h7, h8, h5, h6, X[10], 15);
|
||||
h6 = FF1(h6, h7, h8, h5, X[14], 8);
|
||||
num = h4;
|
||||
h4 = h8;
|
||||
h8 = num;
|
||||
H0 += h;
|
||||
H1 += h2;
|
||||
H2 += h3;
|
||||
H3 += h4;
|
||||
H4 += h5;
|
||||
H5 += h6;
|
||||
H6 += h7;
|
||||
H7 += h8;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new RipeMD256Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
RipeMD256Digest t = (RipeMD256Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class RipeMD320Digest : GeneralDigest
|
||||
{
|
||||
private const int DigestLength = 40;
|
||||
|
||||
private int H0;
|
||||
|
||||
private int H1;
|
||||
|
||||
private int H2;
|
||||
|
||||
private int H3;
|
||||
|
||||
private int H4;
|
||||
|
||||
private int H5;
|
||||
|
||||
private int H6;
|
||||
|
||||
private int H7;
|
||||
|
||||
private int H8;
|
||||
|
||||
private int H9;
|
||||
|
||||
private int[] X = new int[16];
|
||||
|
||||
private int xOff;
|
||||
|
||||
public override string AlgorithmName => "RIPEMD320";
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
|
||||
public RipeMD320Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public RipeMD320Digest(RipeMD320Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(RipeMD320Digest t)
|
||||
{
|
||||
CopyIn((GeneralDigest)t);
|
||||
H0 = t.H0;
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
H4 = t.H4;
|
||||
H5 = t.H5;
|
||||
H6 = t.H6;
|
||||
H7 = t.H7;
|
||||
H8 = t.H8;
|
||||
H9 = t.H9;
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
X[xOff++] = (input[inOff] & 0xFF) | ((input[inOff + 1] & 0xFF) << 8) | ((input[inOff + 2] & 0xFF) << 16) | ((input[inOff + 3] & 0xFF) << 24);
|
||||
if (xOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
X[14] = (int)(bitLength & 0xFFFFFFFFu);
|
||||
X[15] = (int)(bitLength >>> 32);
|
||||
}
|
||||
|
||||
private void UnpackWord(int word, byte[] outBytes, int outOff)
|
||||
{
|
||||
outBytes[outOff] = (byte)word;
|
||||
outBytes[outOff + 1] = (byte)((uint)word >> 8);
|
||||
outBytes[outOff + 2] = (byte)((uint)word >> 16);
|
||||
outBytes[outOff + 3] = (byte)((uint)word >> 24);
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
UnpackWord(H0, output, outOff);
|
||||
UnpackWord(H1, output, outOff + 4);
|
||||
UnpackWord(H2, output, outOff + 8);
|
||||
UnpackWord(H3, output, outOff + 12);
|
||||
UnpackWord(H4, output, outOff + 16);
|
||||
UnpackWord(H5, output, outOff + 20);
|
||||
UnpackWord(H6, output, outOff + 24);
|
||||
UnpackWord(H7, output, outOff + 28);
|
||||
UnpackWord(H8, output, outOff + 32);
|
||||
UnpackWord(H9, output, outOff + 36);
|
||||
Reset();
|
||||
return 40;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H0 = 1732584193;
|
||||
H1 = -271733879;
|
||||
H2 = -1732584194;
|
||||
H3 = 271733878;
|
||||
H4 = -1009589776;
|
||||
H5 = 1985229328;
|
||||
H6 = -19088744;
|
||||
H7 = -1985229329;
|
||||
H8 = 19088743;
|
||||
H9 = 1009589775;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int RL(int x, int n)
|
||||
{
|
||||
return (x << n) | (x >>> 32 - n);
|
||||
}
|
||||
|
||||
private int F1(int x, int y, int z)
|
||||
{
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
private int F2(int x, int y, int z)
|
||||
{
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
|
||||
private int F3(int x, int y, int z)
|
||||
{
|
||||
return (x | ~y) ^ z;
|
||||
}
|
||||
|
||||
private int F4(int x, int y, int z)
|
||||
{
|
||||
return (x & z) | (y & ~z);
|
||||
}
|
||||
|
||||
private int F5(int x, int y, int z)
|
||||
{
|
||||
return x ^ (y | ~z);
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
int h = H0;
|
||||
int h2 = H1;
|
||||
int h3 = H2;
|
||||
int h4 = H3;
|
||||
int h5 = H4;
|
||||
int h6 = H5;
|
||||
int h7 = H6;
|
||||
int h8 = H7;
|
||||
int h9 = H8;
|
||||
int h10 = H9;
|
||||
h = RL(h + F1(h2, h3, h4) + X[0], 11) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F1(h, h2, h3) + X[1], 14) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F1(h5, h, h2) + X[2], 15) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F1(h4, h5, h) + X[3], 12) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F1(h3, h4, h5) + X[4], 5) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F1(h2, h3, h4) + X[5], 8) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F1(h, h2, h3) + X[6], 7) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F1(h5, h, h2) + X[7], 9) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F1(h4, h5, h) + X[8], 11) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F1(h3, h4, h5) + X[9], 13) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F1(h2, h3, h4) + X[10], 14) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F1(h, h2, h3) + X[11], 15) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F1(h5, h, h2) + X[12], 6) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F1(h4, h5, h) + X[13], 7) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F1(h3, h4, h5) + X[14], 9) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F1(h2, h3, h4) + X[15], 8) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h6 = RL(h6 + F5(h7, h8, h9) + X[5] + 1352829926, 8) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F5(h6, h7, h8) + X[14] + 1352829926, 9) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F5(h10, h6, h7) + X[7] + 1352829926, 9) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F5(h9, h10, h6) + X[0] + 1352829926, 11) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F5(h8, h9, h10) + X[9] + 1352829926, 13) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F5(h7, h8, h9) + X[2] + 1352829926, 15) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F5(h6, h7, h8) + X[11] + 1352829926, 15) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F5(h10, h6, h7) + X[4] + 1352829926, 5) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F5(h9, h10, h6) + X[13] + 1352829926, 7) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F5(h8, h9, h10) + X[6] + 1352829926, 7) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F5(h7, h8, h9) + X[15] + 1352829926, 8) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F5(h6, h7, h8) + X[8] + 1352829926, 11) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F5(h10, h6, h7) + X[1] + 1352829926, 14) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F5(h9, h10, h6) + X[10] + 1352829926, 14) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F5(h8, h9, h10) + X[3] + 1352829926, 12) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F5(h7, h8, h9) + X[12] + 1352829926, 6) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
int num = h;
|
||||
h = h6;
|
||||
h6 = num;
|
||||
h5 = RL(h5 + F2(h, h2, h3) + X[7] + 1518500249, 7) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F2(h5, h, h2) + X[4] + 1518500249, 6) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F2(h4, h5, h) + X[13] + 1518500249, 8) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F2(h3, h4, h5) + X[1] + 1518500249, 13) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F2(h2, h3, h4) + X[10] + 1518500249, 11) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F2(h, h2, h3) + X[6] + 1518500249, 9) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F2(h5, h, h2) + X[15] + 1518500249, 7) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F2(h4, h5, h) + X[3] + 1518500249, 15) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F2(h3, h4, h5) + X[12] + 1518500249, 7) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F2(h2, h3, h4) + X[0] + 1518500249, 12) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F2(h, h2, h3) + X[9] + 1518500249, 15) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F2(h5, h, h2) + X[5] + 1518500249, 9) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F2(h4, h5, h) + X[2] + 1518500249, 11) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F2(h3, h4, h5) + X[14] + 1518500249, 7) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F2(h2, h3, h4) + X[11] + 1518500249, 13) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F2(h, h2, h3) + X[8] + 1518500249, 12) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h10 = RL(h10 + F4(h6, h7, h8) + X[6] + 1548603684, 9) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F4(h10, h6, h7) + X[11] + 1548603684, 13) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F4(h9, h10, h6) + X[3] + 1548603684, 15) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F4(h8, h9, h10) + X[7] + 1548603684, 7) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F4(h7, h8, h9) + X[0] + 1548603684, 12) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F4(h6, h7, h8) + X[13] + 1548603684, 8) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F4(h10, h6, h7) + X[5] + 1548603684, 9) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F4(h9, h10, h6) + X[10] + 1548603684, 11) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F4(h8, h9, h10) + X[14] + 1548603684, 7) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F4(h7, h8, h9) + X[15] + 1548603684, 7) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F4(h6, h7, h8) + X[8] + 1548603684, 12) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F4(h10, h6, h7) + X[12] + 1548603684, 7) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F4(h9, h10, h6) + X[4] + 1548603684, 6) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F4(h8, h9, h10) + X[9] + 1548603684, 15) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F4(h7, h8, h9) + X[1] + 1548603684, 13) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F4(h6, h7, h8) + X[2] + 1548603684, 11) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
num = h2;
|
||||
h2 = h7;
|
||||
h7 = num;
|
||||
h4 = RL(h4 + F3(h5, h, h2) + X[3] + 1859775393, 11) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F3(h4, h5, h) + X[10] + 1859775393, 13) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F3(h3, h4, h5) + X[14] + 1859775393, 6) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F3(h2, h3, h4) + X[4] + 1859775393, 7) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F3(h, h2, h3) + X[9] + 1859775393, 14) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F3(h5, h, h2) + X[15] + 1859775393, 9) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F3(h4, h5, h) + X[8] + 1859775393, 13) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F3(h3, h4, h5) + X[1] + 1859775393, 15) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F3(h2, h3, h4) + X[2] + 1859775393, 14) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F3(h, h2, h3) + X[7] + 1859775393, 8) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F3(h5, h, h2) + X[0] + 1859775393, 13) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F3(h4, h5, h) + X[6] + 1859775393, 6) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F3(h3, h4, h5) + X[13] + 1859775393, 5) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F3(h2, h3, h4) + X[11] + 1859775393, 12) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F3(h, h2, h3) + X[5] + 1859775393, 7) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F3(h5, h, h2) + X[12] + 1859775393, 5) + h3;
|
||||
h = RL(h, 10);
|
||||
h9 = RL(h9 + F3(h10, h6, h7) + X[15] + 1836072691, 9) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F3(h9, h10, h6) + X[5] + 1836072691, 7) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F3(h8, h9, h10) + X[1] + 1836072691, 15) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F3(h7, h8, h9) + X[3] + 1836072691, 11) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F3(h6, h7, h8) + X[7] + 1836072691, 8) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F3(h10, h6, h7) + X[14] + 1836072691, 6) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F3(h9, h10, h6) + X[6] + 1836072691, 6) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F3(h8, h9, h10) + X[9] + 1836072691, 14) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F3(h7, h8, h9) + X[11] + 1836072691, 12) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F3(h6, h7, h8) + X[8] + 1836072691, 13) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F3(h10, h6, h7) + X[12] + 1836072691, 5) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F3(h9, h10, h6) + X[2] + 1836072691, 14) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F3(h8, h9, h10) + X[10] + 1836072691, 13) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F3(h7, h8, h9) + X[0] + 1836072691, 13) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F3(h6, h7, h8) + X[4] + 1836072691, 7) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F3(h10, h6, h7) + X[13] + 1836072691, 5) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
num = h3;
|
||||
h3 = h8;
|
||||
h8 = num;
|
||||
h3 = RL(h3 + F4(h4, h5, h) + X[1] + -1894007588, 11) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F4(h3, h4, h5) + X[9] + -1894007588, 12) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F4(h2, h3, h4) + X[11] + -1894007588, 14) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F4(h, h2, h3) + X[10] + -1894007588, 15) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F4(h5, h, h2) + X[0] + -1894007588, 14) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F4(h4, h5, h) + X[8] + -1894007588, 15) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F4(h3, h4, h5) + X[12] + -1894007588, 9) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F4(h2, h3, h4) + X[4] + -1894007588, 8) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F4(h, h2, h3) + X[13] + -1894007588, 9) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F4(h5, h, h2) + X[3] + -1894007588, 14) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F4(h4, h5, h) + X[7] + -1894007588, 5) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F4(h3, h4, h5) + X[15] + -1894007588, 6) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F4(h2, h3, h4) + X[14] + -1894007588, 8) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F4(h, h2, h3) + X[5] + -1894007588, 6) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F4(h5, h, h2) + X[6] + -1894007588, 5) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F4(h4, h5, h) + X[2] + -1894007588, 12) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h8 = RL(h8 + F2(h9, h10, h6) + X[8] + 2053994217, 15) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F2(h8, h9, h10) + X[6] + 2053994217, 5) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F2(h7, h8, h9) + X[4] + 2053994217, 8) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F2(h6, h7, h8) + X[1] + 2053994217, 11) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F2(h10, h6, h7) + X[3] + 2053994217, 14) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F2(h9, h10, h6) + X[11] + 2053994217, 14) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F2(h8, h9, h10) + X[15] + 2053994217, 6) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F2(h7, h8, h9) + X[0] + 2053994217, 14) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F2(h6, h7, h8) + X[5] + 2053994217, 6) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F2(h10, h6, h7) + X[12] + 2053994217, 9) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F2(h9, h10, h6) + X[2] + 2053994217, 12) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F2(h8, h9, h10) + X[13] + 2053994217, 9) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F2(h7, h8, h9) + X[9] + 2053994217, 12) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F2(h6, h7, h8) + X[7] + 2053994217, 5) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F2(h10, h6, h7) + X[10] + 2053994217, 15) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F2(h9, h10, h6) + X[14] + 2053994217, 8) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
num = h4;
|
||||
h4 = h9;
|
||||
h9 = num;
|
||||
h2 = RL(h2 + F5(h3, h4, h5) + X[4] + -1454113458, 9) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F5(h2, h3, h4) + X[0] + -1454113458, 15) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F5(h, h2, h3) + X[5] + -1454113458, 5) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F5(h5, h, h2) + X[9] + -1454113458, 11) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F5(h4, h5, h) + X[7] + -1454113458, 6) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F5(h3, h4, h5) + X[12] + -1454113458, 8) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F5(h2, h3, h4) + X[2] + -1454113458, 13) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F5(h, h2, h3) + X[10] + -1454113458, 12) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F5(h5, h, h2) + X[14] + -1454113458, 5) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F5(h4, h5, h) + X[1] + -1454113458, 12) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F5(h3, h4, h5) + X[3] + -1454113458, 13) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h = RL(h + F5(h2, h3, h4) + X[8] + -1454113458, 14) + h5;
|
||||
h3 = RL(h3, 10);
|
||||
h5 = RL(h5 + F5(h, h2, h3) + X[11] + -1454113458, 11) + h4;
|
||||
h2 = RL(h2, 10);
|
||||
h4 = RL(h4 + F5(h5, h, h2) + X[6] + -1454113458, 8) + h3;
|
||||
h = RL(h, 10);
|
||||
h3 = RL(h3 + F5(h4, h5, h) + X[15] + -1454113458, 5) + h2;
|
||||
h5 = RL(h5, 10);
|
||||
h2 = RL(h2 + F5(h3, h4, h5) + X[13] + -1454113458, 6) + h;
|
||||
h4 = RL(h4, 10);
|
||||
h7 = RL(h7 + F1(h8, h9, h10) + X[12], 8) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F1(h7, h8, h9) + X[15], 5) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F1(h6, h7, h8) + X[10], 12) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F1(h10, h6, h7) + X[4], 9) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F1(h9, h10, h6) + X[1], 12) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F1(h8, h9, h10) + X[5], 5) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F1(h7, h8, h9) + X[8], 14) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F1(h6, h7, h8) + X[7], 6) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F1(h10, h6, h7) + X[6], 8) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F1(h9, h10, h6) + X[2], 13) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F1(h8, h9, h10) + X[13], 6) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
h6 = RL(h6 + F1(h7, h8, h9) + X[14], 5) + h10;
|
||||
h8 = RL(h8, 10);
|
||||
h10 = RL(h10 + F1(h6, h7, h8) + X[0], 15) + h9;
|
||||
h7 = RL(h7, 10);
|
||||
h9 = RL(h9 + F1(h10, h6, h7) + X[3], 13) + h8;
|
||||
h6 = RL(h6, 10);
|
||||
h8 = RL(h8 + F1(h9, h10, h6) + X[9], 11) + h7;
|
||||
h10 = RL(h10, 10);
|
||||
h7 = RL(h7 + F1(h8, h9, h10) + X[11], 11) + h6;
|
||||
h9 = RL(h9, 10);
|
||||
H0 += h;
|
||||
H1 += h2;
|
||||
H2 += h3;
|
||||
H3 += h4;
|
||||
H4 += h10;
|
||||
H5 += h6;
|
||||
H6 += h7;
|
||||
H7 += h8;
|
||||
H8 += h9;
|
||||
H9 += h5;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != X.Length; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new RipeMD320Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
RipeMD320Digest t = (RipeMD320Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class SM3Digest : GeneralDigest
|
||||
{
|
||||
private const int DIGEST_LENGTH = 32;
|
||||
|
||||
private const int BLOCK_SIZE = 16;
|
||||
|
||||
private uint[] V = new uint[8];
|
||||
|
||||
private uint[] inwords = new uint[16];
|
||||
|
||||
private int xOff;
|
||||
|
||||
private uint[] W = new uint[68];
|
||||
|
||||
private static readonly uint[] T;
|
||||
|
||||
public override string AlgorithmName => "SM3";
|
||||
|
||||
static SM3Digest()
|
||||
{
|
||||
T = new uint[64];
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
uint num = 2043430169u;
|
||||
T[i] = (num << i) | (num >> 32 - i);
|
||||
}
|
||||
for (int j = 16; j < 64; j++)
|
||||
{
|
||||
int num2 = j % 32;
|
||||
uint num3 = 2055708042u;
|
||||
T[j] = (num3 << num2) | (num3 >> 32 - num2);
|
||||
}
|
||||
}
|
||||
|
||||
public SM3Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public SM3Digest(SM3Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(SM3Digest t)
|
||||
{
|
||||
Array.Copy(t.V, 0, V, 0, V.Length);
|
||||
Array.Copy(t.inwords, 0, inwords, 0, inwords.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new SM3Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
SM3Digest t = (SM3Digest)other;
|
||||
CopyIn((GeneralDigest)t);
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
V[0] = 1937774191u;
|
||||
V[1] = 1226093241u;
|
||||
V[2] = 388252375u;
|
||||
V[3] = 3666478592u;
|
||||
V[4] = 2842636476u;
|
||||
V[5] = 372324522u;
|
||||
V[6] = 3817729613u;
|
||||
V[7] = 2969243214u;
|
||||
xOff = 0;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
Pack.UInt32_To_BE(V, output, outOff);
|
||||
Reset();
|
||||
return 32;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
uint num = Pack.BE_To_UInt32(input, inOff);
|
||||
inwords[xOff] = num;
|
||||
xOff++;
|
||||
if (xOff >= 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
inwords[xOff] = 0u;
|
||||
xOff++;
|
||||
ProcessBlock();
|
||||
}
|
||||
while (xOff < 14)
|
||||
{
|
||||
inwords[xOff] = 0u;
|
||||
xOff++;
|
||||
}
|
||||
inwords[xOff++] = (uint)(bitLength >> 32);
|
||||
inwords[xOff++] = (uint)bitLength;
|
||||
}
|
||||
|
||||
private uint P0(uint x)
|
||||
{
|
||||
uint num = (x << 9) | (x >> 23);
|
||||
uint num2 = (x << 17) | (x >> 15);
|
||||
return x ^ num ^ num2;
|
||||
}
|
||||
|
||||
private uint P1(uint x)
|
||||
{
|
||||
uint num = (x << 15) | (x >> 17);
|
||||
uint num2 = (x << 23) | (x >> 9);
|
||||
return x ^ num ^ num2;
|
||||
}
|
||||
|
||||
private uint FF0(uint x, uint y, uint z)
|
||||
{
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
private uint FF1(uint x, uint y, uint z)
|
||||
{
|
||||
return (x & y) | (x & z) | (y & z);
|
||||
}
|
||||
|
||||
private uint GG0(uint x, uint y, uint z)
|
||||
{
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
private uint GG1(uint x, uint y, uint z)
|
||||
{
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
W[i] = inwords[i];
|
||||
}
|
||||
for (int j = 16; j < 68; j++)
|
||||
{
|
||||
uint num = W[j - 3];
|
||||
uint num2 = (num << 15) | (num >> 17);
|
||||
uint num3 = W[j - 13];
|
||||
uint num4 = (num3 << 7) | (num3 >> 25);
|
||||
W[j] = P1(W[j - 16] ^ W[j - 9] ^ num2) ^ num4 ^ W[j - 6];
|
||||
}
|
||||
uint num5 = V[0];
|
||||
uint num6 = V[1];
|
||||
uint num7 = V[2];
|
||||
uint num8 = V[3];
|
||||
uint num9 = V[4];
|
||||
uint num10 = V[5];
|
||||
uint num11 = V[6];
|
||||
uint num12 = V[7];
|
||||
for (int k = 0; k < 16; k++)
|
||||
{
|
||||
uint num13 = (num5 << 12) | (num5 >> 20);
|
||||
uint num14 = num13 + num9 + T[k];
|
||||
uint num15 = (num14 << 7) | (num14 >> 25);
|
||||
uint num16 = num15 ^ num13;
|
||||
uint num17 = W[k];
|
||||
uint num18 = num17 ^ W[k + 4];
|
||||
uint num19 = FF0(num5, num6, num7) + num8 + num16 + num18;
|
||||
uint x = GG0(num9, num10, num11) + num12 + num15 + num17;
|
||||
num8 = num7;
|
||||
num7 = (num6 << 9) | (num6 >> 23);
|
||||
num6 = num5;
|
||||
num5 = num19;
|
||||
num12 = num11;
|
||||
num11 = (num10 << 19) | (num10 >> 13);
|
||||
num10 = num9;
|
||||
num9 = P0(x);
|
||||
}
|
||||
for (int l = 16; l < 64; l++)
|
||||
{
|
||||
uint num20 = (num5 << 12) | (num5 >> 20);
|
||||
uint num21 = num20 + num9 + T[l];
|
||||
uint num22 = (num21 << 7) | (num21 >> 25);
|
||||
uint num23 = num22 ^ num20;
|
||||
uint num24 = W[l];
|
||||
uint num25 = num24 ^ W[l + 4];
|
||||
uint num26 = FF1(num5, num6, num7) + num8 + num23 + num25;
|
||||
uint x2 = GG1(num9, num10, num11) + num12 + num22 + num24;
|
||||
num8 = num7;
|
||||
num7 = (num6 << 9) | (num6 >> 23);
|
||||
num6 = num5;
|
||||
num5 = num26;
|
||||
num12 = num11;
|
||||
num11 = (num10 << 19) | (num10 >> 13);
|
||||
num10 = num9;
|
||||
num9 = P0(x2);
|
||||
}
|
||||
uint[] v;
|
||||
(v = V)[0] = v[0] ^ num5;
|
||||
(v = V)[1] = v[1] ^ num6;
|
||||
(v = V)[2] = v[2] ^ num7;
|
||||
(v = V)[3] = v[3] ^ num8;
|
||||
(v = V)[4] = v[4] ^ num9;
|
||||
(v = V)[5] = v[5] ^ num10;
|
||||
(v = V)[6] = v[6] ^ num11;
|
||||
(v = V)[7] = v[7] ^ num12;
|
||||
xOff = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Sha1Digest : GeneralDigest
|
||||
{
|
||||
private const int DigestLength = 20;
|
||||
|
||||
private const uint Y1 = 1518500249u;
|
||||
|
||||
private const uint Y2 = 1859775393u;
|
||||
|
||||
private const uint Y3 = 2400959708u;
|
||||
|
||||
private const uint Y4 = 3395469782u;
|
||||
|
||||
private uint H1;
|
||||
|
||||
private uint H2;
|
||||
|
||||
private uint H3;
|
||||
|
||||
private uint H4;
|
||||
|
||||
private uint H5;
|
||||
|
||||
private uint[] X = new uint[80];
|
||||
|
||||
private int xOff;
|
||||
|
||||
public override string AlgorithmName => "SHA-1";
|
||||
|
||||
public Sha1Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public Sha1Digest(Sha1Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(Sha1Digest t)
|
||||
{
|
||||
CopyIn((GeneralDigest)t);
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
H4 = t.H4;
|
||||
H5 = t.H5;
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
X[xOff] = Pack.BE_To_UInt32(input, inOff);
|
||||
if (++xOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
X[14] = (uint)((ulong)bitLength >> 32);
|
||||
X[15] = (uint)bitLength;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
Pack.UInt32_To_BE(H1, output, outOff);
|
||||
Pack.UInt32_To_BE(H2, output, outOff + 4);
|
||||
Pack.UInt32_To_BE(H3, output, outOff + 8);
|
||||
Pack.UInt32_To_BE(H4, output, outOff + 12);
|
||||
Pack.UInt32_To_BE(H5, output, outOff + 16);
|
||||
Reset();
|
||||
return 20;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H1 = 1732584193u;
|
||||
H2 = 4023233417u;
|
||||
H3 = 2562383102u;
|
||||
H4 = 271733878u;
|
||||
H5 = 3285377520u;
|
||||
xOff = 0;
|
||||
Array.Clear(X, 0, X.Length);
|
||||
}
|
||||
|
||||
private static uint F(uint u, uint v, uint w)
|
||||
{
|
||||
return (u & v) | (~u & w);
|
||||
}
|
||||
|
||||
private static uint H(uint u, uint v, uint w)
|
||||
{
|
||||
return u ^ v ^ w;
|
||||
}
|
||||
|
||||
private static uint G(uint u, uint v, uint w)
|
||||
{
|
||||
return (u & v) | (u & w) | (v & w);
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
for (int i = 16; i < 80; i++)
|
||||
{
|
||||
uint num = X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16];
|
||||
X[i] = (num << 1) | (num >> 31);
|
||||
}
|
||||
uint num2 = H1;
|
||||
uint num3 = H2;
|
||||
uint num4 = H3;
|
||||
uint num5 = H4;
|
||||
uint num6 = H5;
|
||||
int num7 = 0;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
num6 += ((num2 << 5) | (num2 >> 27)) + F(num3, num4, num5) + X[num7++] + 1518500249;
|
||||
num3 = (num3 << 30) | (num3 >> 2);
|
||||
num5 += ((num6 << 5) | (num6 >> 27)) + F(num2, num3, num4) + X[num7++] + 1518500249;
|
||||
num2 = (num2 << 30) | (num2 >> 2);
|
||||
num4 += ((num5 << 5) | (num5 >> 27)) + F(num6, num2, num3) + X[num7++] + 1518500249;
|
||||
num6 = (num6 << 30) | (num6 >> 2);
|
||||
num3 += ((num4 << 5) | (num4 >> 27)) + F(num5, num6, num2) + X[num7++] + 1518500249;
|
||||
num5 = (num5 << 30) | (num5 >> 2);
|
||||
num2 += ((num3 << 5) | (num3 >> 27)) + F(num4, num5, num6) + X[num7++] + 1518500249;
|
||||
num4 = (num4 << 30) | (num4 >> 2);
|
||||
}
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
num6 += ((num2 << 5) | (num2 >> 27)) + H(num3, num4, num5) + X[num7++] + 1859775393;
|
||||
num3 = (num3 << 30) | (num3 >> 2);
|
||||
num5 += ((num6 << 5) | (num6 >> 27)) + H(num2, num3, num4) + X[num7++] + 1859775393;
|
||||
num2 = (num2 << 30) | (num2 >> 2);
|
||||
num4 += ((num5 << 5) | (num5 >> 27)) + H(num6, num2, num3) + X[num7++] + 1859775393;
|
||||
num6 = (num6 << 30) | (num6 >> 2);
|
||||
num3 += ((num4 << 5) | (num4 >> 27)) + H(num5, num6, num2) + X[num7++] + 1859775393;
|
||||
num5 = (num5 << 30) | (num5 >> 2);
|
||||
num2 += ((num3 << 5) | (num3 >> 27)) + H(num4, num5, num6) + X[num7++] + 1859775393;
|
||||
num4 = (num4 << 30) | (num4 >> 2);
|
||||
}
|
||||
for (int l = 0; l < 4; l++)
|
||||
{
|
||||
num6 += (uint)((int)(((num2 << 5) | (num2 >> 27)) + G(num3, num4, num5) + X[num7++]) + -1894007588);
|
||||
num3 = (num3 << 30) | (num3 >> 2);
|
||||
num5 += (uint)((int)(((num6 << 5) | (num6 >> 27)) + G(num2, num3, num4) + X[num7++]) + -1894007588);
|
||||
num2 = (num2 << 30) | (num2 >> 2);
|
||||
num4 += (uint)((int)(((num5 << 5) | (num5 >> 27)) + G(num6, num2, num3) + X[num7++]) + -1894007588);
|
||||
num6 = (num6 << 30) | (num6 >> 2);
|
||||
num3 += (uint)((int)(((num4 << 5) | (num4 >> 27)) + G(num5, num6, num2) + X[num7++]) + -1894007588);
|
||||
num5 = (num5 << 30) | (num5 >> 2);
|
||||
num2 += (uint)((int)(((num3 << 5) | (num3 >> 27)) + G(num4, num5, num6) + X[num7++]) + -1894007588);
|
||||
num4 = (num4 << 30) | (num4 >> 2);
|
||||
}
|
||||
for (int m = 0; m < 4; m++)
|
||||
{
|
||||
num6 += (uint)((int)(((num2 << 5) | (num2 >> 27)) + H(num3, num4, num5) + X[num7++]) + -899497514);
|
||||
num3 = (num3 << 30) | (num3 >> 2);
|
||||
num5 += (uint)((int)(((num6 << 5) | (num6 >> 27)) + H(num2, num3, num4) + X[num7++]) + -899497514);
|
||||
num2 = (num2 << 30) | (num2 >> 2);
|
||||
num4 += (uint)((int)(((num5 << 5) | (num5 >> 27)) + H(num6, num2, num3) + X[num7++]) + -899497514);
|
||||
num6 = (num6 << 30) | (num6 >> 2);
|
||||
num3 += (uint)((int)(((num4 << 5) | (num4 >> 27)) + H(num5, num6, num2) + X[num7++]) + -899497514);
|
||||
num5 = (num5 << 30) | (num5 >> 2);
|
||||
num2 += (uint)((int)(((num3 << 5) | (num3 >> 27)) + H(num4, num5, num6) + X[num7++]) + -899497514);
|
||||
num4 = (num4 << 30) | (num4 >> 2);
|
||||
}
|
||||
H1 += num2;
|
||||
H2 += num3;
|
||||
H3 += num4;
|
||||
H4 += num5;
|
||||
H5 += num6;
|
||||
xOff = 0;
|
||||
Array.Clear(X, 0, 16);
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new Sha1Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
Sha1Digest t = (Sha1Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Sha224Digest : GeneralDigest
|
||||
{
|
||||
private const int DigestLength = 28;
|
||||
|
||||
private uint H1;
|
||||
|
||||
private uint H2;
|
||||
|
||||
private uint H3;
|
||||
|
||||
private uint H4;
|
||||
|
||||
private uint H5;
|
||||
|
||||
private uint H6;
|
||||
|
||||
private uint H7;
|
||||
|
||||
private uint H8;
|
||||
|
||||
private uint[] X = new uint[64];
|
||||
|
||||
private int xOff;
|
||||
|
||||
internal static readonly uint[] K = new uint[64]
|
||||
{
|
||||
1116352408u, 1899447441u, 3049323471u, 3921009573u, 961987163u, 1508970993u, 2453635748u, 2870763221u, 3624381080u, 310598401u,
|
||||
607225278u, 1426881987u, 1925078388u, 2162078206u, 2614888103u, 3248222580u, 3835390401u, 4022224774u, 264347078u, 604807628u,
|
||||
770255983u, 1249150122u, 1555081692u, 1996064986u, 2554220882u, 2821834349u, 2952996808u, 3210313671u, 3336571891u, 3584528711u,
|
||||
113926993u, 338241895u, 666307205u, 773529912u, 1294757372u, 1396182291u, 1695183700u, 1986661051u, 2177026350u, 2456956037u,
|
||||
2730485921u, 2820302411u, 3259730800u, 3345764771u, 3516065817u, 3600352804u, 4094571909u, 275423344u, 430227734u, 506948616u,
|
||||
659060556u, 883997877u, 958139571u, 1322822218u, 1537002063u, 1747873779u, 1955562222u, 2024104815u, 2227730452u, 2361852424u,
|
||||
2428436474u, 2756734187u, 3204031479u, 3329325298u
|
||||
};
|
||||
|
||||
public override string AlgorithmName => "SHA-224";
|
||||
|
||||
public Sha224Digest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public Sha224Digest(Sha224Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(Sha224Digest t)
|
||||
{
|
||||
CopyIn((GeneralDigest)t);
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
H4 = t.H4;
|
||||
H5 = t.H5;
|
||||
H6 = t.H6;
|
||||
H7 = t.H7;
|
||||
H8 = t.H8;
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 28;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
X[xOff] = Pack.BE_To_UInt32(input, inOff);
|
||||
if (++xOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
X[14] = (uint)((ulong)bitLength >> 32);
|
||||
X[15] = (uint)bitLength;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
Pack.UInt32_To_BE(H1, output, outOff);
|
||||
Pack.UInt32_To_BE(H2, output, outOff + 4);
|
||||
Pack.UInt32_To_BE(H3, output, outOff + 8);
|
||||
Pack.UInt32_To_BE(H4, output, outOff + 12);
|
||||
Pack.UInt32_To_BE(H5, output, outOff + 16);
|
||||
Pack.UInt32_To_BE(H6, output, outOff + 20);
|
||||
Pack.UInt32_To_BE(H7, output, outOff + 24);
|
||||
Reset();
|
||||
return 28;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H1 = 3238371032u;
|
||||
H2 = 914150663u;
|
||||
H3 = 812702999u;
|
||||
H4 = 4144912697u;
|
||||
H5 = 4290775857u;
|
||||
H6 = 1750603025u;
|
||||
H7 = 1694076839u;
|
||||
H8 = 3204075428u;
|
||||
xOff = 0;
|
||||
Array.Clear(X, 0, X.Length);
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
for (int i = 16; i <= 63; i++)
|
||||
{
|
||||
X[i] = Theta1(X[i - 2]) + X[i - 7] + Theta0(X[i - 15]) + X[i - 16];
|
||||
}
|
||||
uint num = H1;
|
||||
uint num2 = H2;
|
||||
uint num3 = H3;
|
||||
uint num4 = H4;
|
||||
uint num5 = H5;
|
||||
uint num6 = H6;
|
||||
uint num7 = H7;
|
||||
uint num8 = H8;
|
||||
int num9 = 0;
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
num8 += Sum1(num5) + Ch(num5, num6, num7) + K[num9] + X[num9];
|
||||
num4 += num8;
|
||||
num8 += Sum0(num) + Maj(num, num2, num3);
|
||||
num9++;
|
||||
num7 += Sum1(num4) + Ch(num4, num5, num6) + K[num9] + X[num9];
|
||||
num3 += num7;
|
||||
num7 += Sum0(num8) + Maj(num8, num, num2);
|
||||
num9++;
|
||||
num6 += Sum1(num3) + Ch(num3, num4, num5) + K[num9] + X[num9];
|
||||
num2 += num6;
|
||||
num6 += Sum0(num7) + Maj(num7, num8, num);
|
||||
num9++;
|
||||
num5 += Sum1(num2) + Ch(num2, num3, num4) + K[num9] + X[num9];
|
||||
num += num5;
|
||||
num5 += Sum0(num6) + Maj(num6, num7, num8);
|
||||
num9++;
|
||||
num4 += Sum1(num) + Ch(num, num2, num3) + K[num9] + X[num9];
|
||||
num8 += num4;
|
||||
num4 += Sum0(num5) + Maj(num5, num6, num7);
|
||||
num9++;
|
||||
num3 += Sum1(num8) + Ch(num8, num, num2) + K[num9] + X[num9];
|
||||
num7 += num3;
|
||||
num3 += Sum0(num4) + Maj(num4, num5, num6);
|
||||
num9++;
|
||||
num2 += Sum1(num7) + Ch(num7, num8, num) + K[num9] + X[num9];
|
||||
num6 += num2;
|
||||
num2 += Sum0(num3) + Maj(num3, num4, num5);
|
||||
num9++;
|
||||
num += Sum1(num6) + Ch(num6, num7, num8) + K[num9] + X[num9];
|
||||
num5 += num;
|
||||
num += Sum0(num2) + Maj(num2, num3, num4);
|
||||
num9++;
|
||||
}
|
||||
H1 += num;
|
||||
H2 += num2;
|
||||
H3 += num3;
|
||||
H4 += num4;
|
||||
H5 += num5;
|
||||
H6 += num6;
|
||||
H7 += num7;
|
||||
H8 += num8;
|
||||
xOff = 0;
|
||||
Array.Clear(X, 0, 16);
|
||||
}
|
||||
|
||||
private static uint Ch(uint x, uint y, uint z)
|
||||
{
|
||||
return (x & y) ^ (~x & z);
|
||||
}
|
||||
|
||||
private static uint Maj(uint x, uint y, uint z)
|
||||
{
|
||||
return (x & y) ^ (x & z) ^ (y & z);
|
||||
}
|
||||
|
||||
private static uint Sum0(uint x)
|
||||
{
|
||||
return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10));
|
||||
}
|
||||
|
||||
private static uint Sum1(uint x)
|
||||
{
|
||||
return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7));
|
||||
}
|
||||
|
||||
private static uint Theta0(uint x)
|
||||
{
|
||||
return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3);
|
||||
}
|
||||
|
||||
private static uint Theta1(uint x)
|
||||
{
|
||||
return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10);
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new Sha224Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
Sha224Digest t = (Sha224Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Sha256Digest : GeneralDigest
|
||||
{
|
||||
private const int DigestLength = 32;
|
||||
|
||||
private uint H1;
|
||||
|
||||
private uint H2;
|
||||
|
||||
private uint H3;
|
||||
|
||||
private uint H4;
|
||||
|
||||
private uint H5;
|
||||
|
||||
private uint H6;
|
||||
|
||||
private uint H7;
|
||||
|
||||
private uint H8;
|
||||
|
||||
private uint[] X = new uint[64];
|
||||
|
||||
private int xOff;
|
||||
|
||||
private static readonly uint[] K = new uint[64]
|
||||
{
|
||||
1116352408u, 1899447441u, 3049323471u, 3921009573u, 961987163u, 1508970993u, 2453635748u, 2870763221u, 3624381080u, 310598401u,
|
||||
607225278u, 1426881987u, 1925078388u, 2162078206u, 2614888103u, 3248222580u, 3835390401u, 4022224774u, 264347078u, 604807628u,
|
||||
770255983u, 1249150122u, 1555081692u, 1996064986u, 2554220882u, 2821834349u, 2952996808u, 3210313671u, 3336571891u, 3584528711u,
|
||||
113926993u, 338241895u, 666307205u, 773529912u, 1294757372u, 1396182291u, 1695183700u, 1986661051u, 2177026350u, 2456956037u,
|
||||
2730485921u, 2820302411u, 3259730800u, 3345764771u, 3516065817u, 3600352804u, 4094571909u, 275423344u, 430227734u, 506948616u,
|
||||
659060556u, 883997877u, 958139571u, 1322822218u, 1537002063u, 1747873779u, 1955562222u, 2024104815u, 2227730452u, 2361852424u,
|
||||
2428436474u, 2756734187u, 3204031479u, 3329325298u
|
||||
};
|
||||
|
||||
public override string AlgorithmName => "SHA-256";
|
||||
|
||||
public Sha256Digest()
|
||||
{
|
||||
initHs();
|
||||
}
|
||||
|
||||
public Sha256Digest(Sha256Digest t)
|
||||
: base(t)
|
||||
{
|
||||
CopyIn(t);
|
||||
}
|
||||
|
||||
private void CopyIn(Sha256Digest t)
|
||||
{
|
||||
CopyIn((GeneralDigest)t);
|
||||
H1 = t.H1;
|
||||
H2 = t.H2;
|
||||
H3 = t.H3;
|
||||
H4 = t.H4;
|
||||
H5 = t.H5;
|
||||
H6 = t.H6;
|
||||
H7 = t.H7;
|
||||
H8 = t.H8;
|
||||
Array.Copy(t.X, 0, X, 0, t.X.Length);
|
||||
xOff = t.xOff;
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
internal override void ProcessWord(byte[] input, int inOff)
|
||||
{
|
||||
X[xOff] = Pack.BE_To_UInt32(input, inOff);
|
||||
if (++xOff == 16)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessLength(long bitLength)
|
||||
{
|
||||
if (xOff > 14)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
X[14] = (uint)((ulong)bitLength >> 32);
|
||||
X[15] = (uint)bitLength;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
Pack.UInt32_To_BE(H1, output, outOff);
|
||||
Pack.UInt32_To_BE(H2, output, outOff + 4);
|
||||
Pack.UInt32_To_BE(H3, output, outOff + 8);
|
||||
Pack.UInt32_To_BE(H4, output, outOff + 12);
|
||||
Pack.UInt32_To_BE(H5, output, outOff + 16);
|
||||
Pack.UInt32_To_BE(H6, output, outOff + 20);
|
||||
Pack.UInt32_To_BE(H7, output, outOff + 24);
|
||||
Pack.UInt32_To_BE(H8, output, outOff + 28);
|
||||
Reset();
|
||||
return 32;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
initHs();
|
||||
xOff = 0;
|
||||
Array.Clear(X, 0, X.Length);
|
||||
}
|
||||
|
||||
private void initHs()
|
||||
{
|
||||
H1 = 1779033703u;
|
||||
H2 = 3144134277u;
|
||||
H3 = 1013904242u;
|
||||
H4 = 2773480762u;
|
||||
H5 = 1359893119u;
|
||||
H6 = 2600822924u;
|
||||
H7 = 528734635u;
|
||||
H8 = 1541459225u;
|
||||
}
|
||||
|
||||
internal override void ProcessBlock()
|
||||
{
|
||||
for (int i = 16; i <= 63; i++)
|
||||
{
|
||||
X[i] = Theta1(X[i - 2]) + X[i - 7] + Theta0(X[i - 15]) + X[i - 16];
|
||||
}
|
||||
uint num = H1;
|
||||
uint num2 = H2;
|
||||
uint num3 = H3;
|
||||
uint num4 = H4;
|
||||
uint num5 = H5;
|
||||
uint num6 = H6;
|
||||
uint num7 = H7;
|
||||
uint num8 = H8;
|
||||
int num9 = 0;
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
num8 += Sum1Ch(num5, num6, num7) + K[num9] + X[num9];
|
||||
num4 += num8;
|
||||
num8 += Sum0Maj(num, num2, num3);
|
||||
num9++;
|
||||
num7 += Sum1Ch(num4, num5, num6) + K[num9] + X[num9];
|
||||
num3 += num7;
|
||||
num7 += Sum0Maj(num8, num, num2);
|
||||
num9++;
|
||||
num6 += Sum1Ch(num3, num4, num5) + K[num9] + X[num9];
|
||||
num2 += num6;
|
||||
num6 += Sum0Maj(num7, num8, num);
|
||||
num9++;
|
||||
num5 += Sum1Ch(num2, num3, num4) + K[num9] + X[num9];
|
||||
num += num5;
|
||||
num5 += Sum0Maj(num6, num7, num8);
|
||||
num9++;
|
||||
num4 += Sum1Ch(num, num2, num3) + K[num9] + X[num9];
|
||||
num8 += num4;
|
||||
num4 += Sum0Maj(num5, num6, num7);
|
||||
num9++;
|
||||
num3 += Sum1Ch(num8, num, num2) + K[num9] + X[num9];
|
||||
num7 += num3;
|
||||
num3 += Sum0Maj(num4, num5, num6);
|
||||
num9++;
|
||||
num2 += Sum1Ch(num7, num8, num) + K[num9] + X[num9];
|
||||
num6 += num2;
|
||||
num2 += Sum0Maj(num3, num4, num5);
|
||||
num9++;
|
||||
num += Sum1Ch(num6, num7, num8) + K[num9] + X[num9];
|
||||
num5 += num;
|
||||
num += Sum0Maj(num2, num3, num4);
|
||||
num9++;
|
||||
}
|
||||
H1 += num;
|
||||
H2 += num2;
|
||||
H3 += num3;
|
||||
H4 += num4;
|
||||
H5 += num5;
|
||||
H6 += num6;
|
||||
H7 += num7;
|
||||
H8 += num8;
|
||||
xOff = 0;
|
||||
Array.Clear(X, 0, 16);
|
||||
}
|
||||
|
||||
private static uint Sum1Ch(uint x, uint y, uint z)
|
||||
{
|
||||
return (((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))) + ((x & y) ^ (~x & z));
|
||||
}
|
||||
|
||||
private static uint Sum0Maj(uint x, uint y, uint z)
|
||||
{
|
||||
return (((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))) + ((x & y) ^ (x & z) ^ (y & z));
|
||||
}
|
||||
|
||||
private static uint Theta0(uint x)
|
||||
{
|
||||
return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3);
|
||||
}
|
||||
|
||||
private static uint Theta1(uint x)
|
||||
{
|
||||
return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10);
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new Sha256Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
Sha256Digest t = (Sha256Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Sha384Digest : LongDigest
|
||||
{
|
||||
private const int DigestLength = 48;
|
||||
|
||||
public override string AlgorithmName => "SHA-384";
|
||||
|
||||
public Sha384Digest()
|
||||
{
|
||||
}
|
||||
|
||||
public Sha384Digest(Sha384Digest t)
|
||||
: base(t)
|
||||
{
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 48;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
Pack.UInt64_To_BE(H1, output, outOff);
|
||||
Pack.UInt64_To_BE(H2, output, outOff + 8);
|
||||
Pack.UInt64_To_BE(H3, output, outOff + 16);
|
||||
Pack.UInt64_To_BE(H4, output, outOff + 24);
|
||||
Pack.UInt64_To_BE(H5, output, outOff + 32);
|
||||
Pack.UInt64_To_BE(H6, output, outOff + 40);
|
||||
Reset();
|
||||
return 48;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H1 = 14680500436340154072uL;
|
||||
H2 = 7105036623409894663uL;
|
||||
H3 = 10473403895298186519uL;
|
||||
H4 = 1526699215303891257uL;
|
||||
H5 = 7436329637833083697uL;
|
||||
H6 = 10282925794625328401uL;
|
||||
H7 = 15784041429090275239uL;
|
||||
H8 = 5167115440072839076uL;
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new Sha384Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
Sha384Digest t = (Sha384Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Sha3Digest : KeccakDigest
|
||||
{
|
||||
public override string AlgorithmName => "SHA3-" + fixedOutputLength;
|
||||
|
||||
private static int CheckBitLength(int bitLength)
|
||||
{
|
||||
switch (bitLength)
|
||||
{
|
||||
case 224:
|
||||
case 256:
|
||||
case 384:
|
||||
case 512:
|
||||
return bitLength;
|
||||
default:
|
||||
throw new ArgumentException(bitLength + " not supported for SHA-3", "bitLength");
|
||||
}
|
||||
}
|
||||
|
||||
public Sha3Digest()
|
||||
: this(256)
|
||||
{
|
||||
}
|
||||
|
||||
public Sha3Digest(int bitLength)
|
||||
: base(CheckBitLength(bitLength))
|
||||
{
|
||||
}
|
||||
|
||||
public Sha3Digest(Sha3Digest source)
|
||||
: base(source)
|
||||
{
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
AbsorbBits(2, 2);
|
||||
return base.DoFinal(output, outOff);
|
||||
}
|
||||
|
||||
protected override int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits)
|
||||
{
|
||||
if (partialBits < 0 || partialBits > 7)
|
||||
{
|
||||
throw new ArgumentException("must be in the range [0,7]", "partialBits");
|
||||
}
|
||||
int num = (partialByte & ((1 << partialBits) - 1)) | (2 << partialBits);
|
||||
int num2 = partialBits + 2;
|
||||
if (num2 >= 8)
|
||||
{
|
||||
Absorb(new byte[1] { (byte)num }, 0, 1);
|
||||
num2 -= 8;
|
||||
num >>= 8;
|
||||
}
|
||||
return base.DoFinal(output, outOff, (byte)num, num2);
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new Sha3Digest(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Sha512Digest : LongDigest
|
||||
{
|
||||
private const int DigestLength = 64;
|
||||
|
||||
public override string AlgorithmName => "SHA-512";
|
||||
|
||||
public Sha512Digest()
|
||||
{
|
||||
}
|
||||
|
||||
public Sha512Digest(Sha512Digest t)
|
||||
: base(t)
|
||||
{
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
Pack.UInt64_To_BE(H1, output, outOff);
|
||||
Pack.UInt64_To_BE(H2, output, outOff + 8);
|
||||
Pack.UInt64_To_BE(H3, output, outOff + 16);
|
||||
Pack.UInt64_To_BE(H4, output, outOff + 24);
|
||||
Pack.UInt64_To_BE(H5, output, outOff + 32);
|
||||
Pack.UInt64_To_BE(H6, output, outOff + 40);
|
||||
Pack.UInt64_To_BE(H7, output, outOff + 48);
|
||||
Pack.UInt64_To_BE(H8, output, outOff + 56);
|
||||
Reset();
|
||||
return 64;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H1 = 7640891576956012808uL;
|
||||
H2 = 13503953896175478587uL;
|
||||
H3 = 4354685564936845355uL;
|
||||
H4 = 11912009170470909681uL;
|
||||
H5 = 5840696475078001361uL;
|
||||
H6 = 11170449401992604703uL;
|
||||
H7 = 2270897969802886507uL;
|
||||
H8 = 6620516959819538809uL;
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new Sha512Digest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
Sha512Digest t = (Sha512Digest)other;
|
||||
CopyIn(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class Sha512tDigest : LongDigest
|
||||
{
|
||||
private const ulong A5 = 11936128518282651045uL;
|
||||
|
||||
private readonly int digestLength;
|
||||
|
||||
private ulong H1t;
|
||||
|
||||
private ulong H2t;
|
||||
|
||||
private ulong H3t;
|
||||
|
||||
private ulong H4t;
|
||||
|
||||
private ulong H5t;
|
||||
|
||||
private ulong H6t;
|
||||
|
||||
private ulong H7t;
|
||||
|
||||
private ulong H8t;
|
||||
|
||||
public override string AlgorithmName => "SHA-512/" + digestLength * 8;
|
||||
|
||||
public Sha512tDigest(int bitLength)
|
||||
{
|
||||
if (bitLength >= 512)
|
||||
{
|
||||
throw new ArgumentException("cannot be >= 512", "bitLength");
|
||||
}
|
||||
if (bitLength % 8 != 0)
|
||||
{
|
||||
throw new ArgumentException("needs to be a multiple of 8", "bitLength");
|
||||
}
|
||||
if (bitLength == 384)
|
||||
{
|
||||
throw new ArgumentException("cannot be 384 use SHA384 instead", "bitLength");
|
||||
}
|
||||
digestLength = bitLength / 8;
|
||||
tIvGenerate(digestLength * 8);
|
||||
Reset();
|
||||
}
|
||||
|
||||
public Sha512tDigest(Sha512tDigest t)
|
||||
: base(t)
|
||||
{
|
||||
digestLength = t.digestLength;
|
||||
Reset(t);
|
||||
}
|
||||
|
||||
public override int GetDigestSize()
|
||||
{
|
||||
return digestLength;
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
UInt64_To_BE(H1, output, outOff, digestLength);
|
||||
UInt64_To_BE(H2, output, outOff + 8, digestLength - 8);
|
||||
UInt64_To_BE(H3, output, outOff + 16, digestLength - 16);
|
||||
UInt64_To_BE(H4, output, outOff + 24, digestLength - 24);
|
||||
UInt64_To_BE(H5, output, outOff + 32, digestLength - 32);
|
||||
UInt64_To_BE(H6, output, outOff + 40, digestLength - 40);
|
||||
UInt64_To_BE(H7, output, outOff + 48, digestLength - 48);
|
||||
UInt64_To_BE(H8, output, outOff + 56, digestLength - 56);
|
||||
Reset();
|
||||
return digestLength;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
H1 = H1t;
|
||||
H2 = H2t;
|
||||
H3 = H3t;
|
||||
H4 = H4t;
|
||||
H5 = H5t;
|
||||
H6 = H6t;
|
||||
H7 = H7t;
|
||||
H8 = H8t;
|
||||
}
|
||||
|
||||
private void tIvGenerate(int bitLength)
|
||||
{
|
||||
H1 = 14964410163792538797uL;
|
||||
H2 = 2216346199247487646uL;
|
||||
H3 = 11082046791023156622uL;
|
||||
H4 = 65953792586715988uL;
|
||||
H5 = 17630457682085488500uL;
|
||||
H6 = 4512832404995164602uL;
|
||||
H7 = 13413544941332994254uL;
|
||||
H8 = 18322165818757711068uL;
|
||||
Update(83);
|
||||
Update(72);
|
||||
Update(65);
|
||||
Update(45);
|
||||
Update(53);
|
||||
Update(49);
|
||||
Update(50);
|
||||
Update(47);
|
||||
if (bitLength > 100)
|
||||
{
|
||||
Update((byte)(bitLength / 100 + 48));
|
||||
bitLength %= 100;
|
||||
Update((byte)(bitLength / 10 + 48));
|
||||
bitLength %= 10;
|
||||
Update((byte)(bitLength + 48));
|
||||
}
|
||||
else if (bitLength > 10)
|
||||
{
|
||||
Update((byte)(bitLength / 10 + 48));
|
||||
bitLength %= 10;
|
||||
Update((byte)(bitLength + 48));
|
||||
}
|
||||
else
|
||||
{
|
||||
Update((byte)(bitLength + 48));
|
||||
}
|
||||
Finish();
|
||||
H1t = H1;
|
||||
H2t = H2;
|
||||
H3t = H3;
|
||||
H4t = H4;
|
||||
H5t = H5;
|
||||
H6t = H6;
|
||||
H7t = H7;
|
||||
H8t = H8;
|
||||
}
|
||||
|
||||
private static void UInt64_To_BE(ulong n, byte[] bs, int off, int max)
|
||||
{
|
||||
if (max > 0)
|
||||
{
|
||||
UInt32_To_BE((uint)(n >> 32), bs, off, max);
|
||||
if (max > 4)
|
||||
{
|
||||
UInt32_To_BE((uint)n, bs, off + 4, max - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void UInt32_To_BE(uint n, byte[] bs, int off, int max)
|
||||
{
|
||||
int num = System.Math.Min(4, max);
|
||||
while (--num >= 0)
|
||||
{
|
||||
int num2 = 8 * (3 - num);
|
||||
bs[off + num] = (byte)(n >> num2);
|
||||
}
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new Sha512tDigest(this);
|
||||
}
|
||||
|
||||
public override void Reset(IMemoable other)
|
||||
{
|
||||
Sha512tDigest sha512tDigest = (Sha512tDigest)other;
|
||||
if (digestLength != sha512tDigest.digestLength)
|
||||
{
|
||||
throw new MemoableResetException("digestLength inappropriate in other");
|
||||
}
|
||||
CopyIn(sha512tDigest);
|
||||
H1t = sha512tDigest.H1t;
|
||||
H2t = sha512tDigest.H2t;
|
||||
H3t = sha512tDigest.H3t;
|
||||
H4t = sha512tDigest.H4t;
|
||||
H5t = sha512tDigest.H5t;
|
||||
H6t = sha512tDigest.H6t;
|
||||
H7t = sha512tDigest.H7t;
|
||||
H8t = sha512tDigest.H8t;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class ShakeDigest : KeccakDigest, IXof, IDigest
|
||||
{
|
||||
public override string AlgorithmName => "SHAKE" + fixedOutputLength;
|
||||
|
||||
private static int CheckBitLength(int bitLength)
|
||||
{
|
||||
if (bitLength == 128 || bitLength == 256)
|
||||
{
|
||||
return bitLength;
|
||||
}
|
||||
throw new ArgumentException(bitLength + " not supported for SHAKE", "bitLength");
|
||||
}
|
||||
|
||||
public ShakeDigest()
|
||||
: this(128)
|
||||
{
|
||||
}
|
||||
|
||||
public ShakeDigest(int bitLength)
|
||||
: base(CheckBitLength(bitLength))
|
||||
{
|
||||
}
|
||||
|
||||
public ShakeDigest(ShakeDigest source)
|
||||
: base(source)
|
||||
{
|
||||
}
|
||||
|
||||
public override int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
return DoFinal(output, outOff, GetDigestSize());
|
||||
}
|
||||
|
||||
public virtual int DoFinal(byte[] output, int outOff, int outLen)
|
||||
{
|
||||
DoOutput(output, outOff, outLen);
|
||||
Reset();
|
||||
return outLen;
|
||||
}
|
||||
|
||||
public virtual int DoOutput(byte[] output, int outOff, int outLen)
|
||||
{
|
||||
if (!squeezing)
|
||||
{
|
||||
AbsorbBits(15, 4);
|
||||
}
|
||||
Squeeze(output, outOff, (long)outLen << 3);
|
||||
return outLen;
|
||||
}
|
||||
|
||||
protected override int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits)
|
||||
{
|
||||
return DoFinal(output, outOff, GetDigestSize(), partialByte, partialBits);
|
||||
}
|
||||
|
||||
protected virtual int DoFinal(byte[] output, int outOff, int outLen, byte partialByte, int partialBits)
|
||||
{
|
||||
if (partialBits < 0 || partialBits > 7)
|
||||
{
|
||||
throw new ArgumentException("must be in the range [0,7]", "partialBits");
|
||||
}
|
||||
int num = (partialByte & ((1 << partialBits) - 1)) | (15 << partialBits);
|
||||
int num2 = partialBits + 4;
|
||||
if (num2 >= 8)
|
||||
{
|
||||
Absorb(new byte[1] { (byte)num }, 0, 1);
|
||||
num2 -= 8;
|
||||
num >>= 8;
|
||||
}
|
||||
if (num2 > 0)
|
||||
{
|
||||
AbsorbBits(num, num2);
|
||||
}
|
||||
Squeeze(output, outOff, (long)outLen << 3);
|
||||
Reset();
|
||||
return outLen;
|
||||
}
|
||||
|
||||
public override IMemoable Copy()
|
||||
{
|
||||
return new ShakeDigest(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class ShortenedDigest : IDigest
|
||||
{
|
||||
private IDigest baseDigest;
|
||||
|
||||
private int length;
|
||||
|
||||
public string AlgorithmName => baseDigest.AlgorithmName + "(" + length * 8 + ")";
|
||||
|
||||
public ShortenedDigest(IDigest baseDigest, int length)
|
||||
{
|
||||
if (baseDigest == null)
|
||||
{
|
||||
throw new ArgumentNullException("baseDigest");
|
||||
}
|
||||
if (length > baseDigest.GetDigestSize())
|
||||
{
|
||||
throw new ArgumentException("baseDigest output not large enough to support length");
|
||||
}
|
||||
this.baseDigest = baseDigest;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public int GetDigestSize()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
public void Update(byte input)
|
||||
{
|
||||
baseDigest.Update(input);
|
||||
}
|
||||
|
||||
public void BlockUpdate(byte[] input, int inOff, int length)
|
||||
{
|
||||
baseDigest.BlockUpdate(input, inOff, length);
|
||||
}
|
||||
|
||||
public int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
byte[] array = new byte[baseDigest.GetDigestSize()];
|
||||
baseDigest.DoFinal(array, 0);
|
||||
Array.Copy(array, 0, output, outOff, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
baseDigest.Reset();
|
||||
}
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return baseDigest.GetByteLength();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class SkeinDigest : IDigest, IMemoable
|
||||
{
|
||||
public const int SKEIN_256 = 256;
|
||||
|
||||
public const int SKEIN_512 = 512;
|
||||
|
||||
public const int SKEIN_1024 = 1024;
|
||||
|
||||
private readonly SkeinEngine engine;
|
||||
|
||||
public string AlgorithmName => "Skein-" + engine.BlockSize * 8 + "-" + engine.OutputSize * 8;
|
||||
|
||||
public SkeinDigest(int stateSizeBits, int digestSizeBits)
|
||||
{
|
||||
engine = new SkeinEngine(stateSizeBits, digestSizeBits);
|
||||
Init(null);
|
||||
}
|
||||
|
||||
public SkeinDigest(SkeinDigest digest)
|
||||
{
|
||||
engine = new SkeinEngine(digest.engine);
|
||||
}
|
||||
|
||||
public void Reset(IMemoable other)
|
||||
{
|
||||
SkeinDigest skeinDigest = (SkeinDigest)other;
|
||||
engine.Reset(skeinDigest.engine);
|
||||
}
|
||||
|
||||
public IMemoable Copy()
|
||||
{
|
||||
return new SkeinDigest(this);
|
||||
}
|
||||
|
||||
public int GetDigestSize()
|
||||
{
|
||||
return engine.OutputSize;
|
||||
}
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return engine.BlockSize;
|
||||
}
|
||||
|
||||
public void Init(SkeinParameters parameters)
|
||||
{
|
||||
engine.Init(parameters);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
engine.Reset();
|
||||
}
|
||||
|
||||
public void Update(byte inByte)
|
||||
{
|
||||
engine.Update(inByte);
|
||||
}
|
||||
|
||||
public void BlockUpdate(byte[] inBytes, int inOff, int len)
|
||||
{
|
||||
engine.Update(inBytes, inOff, len);
|
||||
}
|
||||
|
||||
public int DoFinal(byte[] outBytes, int outOff)
|
||||
{
|
||||
return engine.DoFinal(outBytes, outOff);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Crypto.Engines;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class SkeinEngine : IMemoable
|
||||
{
|
||||
private class Configuration
|
||||
{
|
||||
private byte[] bytes = new byte[32];
|
||||
|
||||
public byte[] Bytes => bytes;
|
||||
|
||||
public Configuration(long outputSizeBits)
|
||||
{
|
||||
bytes[0] = 83;
|
||||
bytes[1] = 72;
|
||||
bytes[2] = 65;
|
||||
bytes[3] = 51;
|
||||
bytes[4] = 1;
|
||||
bytes[5] = 0;
|
||||
ThreefishEngine.WordToBytes((ulong)outputSizeBits, bytes, 8);
|
||||
}
|
||||
}
|
||||
|
||||
public class Parameter
|
||||
{
|
||||
private int type;
|
||||
|
||||
private byte[] value;
|
||||
|
||||
public int Type => type;
|
||||
|
||||
public byte[] Value => value;
|
||||
|
||||
public Parameter(int type, byte[] value)
|
||||
{
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class UbiTweak
|
||||
{
|
||||
private const ulong LOW_RANGE = 18446744069414584320uL;
|
||||
|
||||
private const ulong T1_FINAL = 9223372036854775808uL;
|
||||
|
||||
private const ulong T1_FIRST = 4611686018427387904uL;
|
||||
|
||||
private ulong[] tweak = new ulong[2];
|
||||
|
||||
private bool extendedPosition;
|
||||
|
||||
public uint Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return (uint)((tweak[1] >> 56) & 0x3F);
|
||||
}
|
||||
set
|
||||
{
|
||||
tweak[1] = (tweak[1] & 0xFFFFFFC000000000uL) | (((ulong)value & 0x3FuL) << 56);
|
||||
}
|
||||
}
|
||||
|
||||
public bool First
|
||||
{
|
||||
get
|
||||
{
|
||||
return (tweak[1] & 0x4000000000000000L) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
ulong[] array;
|
||||
(array = tweak)[1] = array[1] | 0x4000000000000000L;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong[] array;
|
||||
(array = tweak)[1] = array[1] & 0xBFFFFFFFFFFFFFFFuL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Final
|
||||
{
|
||||
get
|
||||
{
|
||||
return (tweak[1] & 0x8000000000000000uL) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
ulong[] array;
|
||||
(array = tweak)[1] = array[1] | 0x8000000000000000uL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong[] array;
|
||||
(array = tweak)[1] = array[1] & 0x7FFFFFFFFFFFFFFFL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UbiTweak()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Reset(UbiTweak tweak)
|
||||
{
|
||||
this.tweak = Arrays.Clone(tweak.tweak, this.tweak);
|
||||
extendedPosition = tweak.extendedPosition;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
tweak[0] = 0uL;
|
||||
tweak[1] = 0uL;
|
||||
extendedPosition = false;
|
||||
First = true;
|
||||
}
|
||||
|
||||
public void AdvancePosition(int advance)
|
||||
{
|
||||
if (extendedPosition)
|
||||
{
|
||||
ulong[] array = new ulong[3]
|
||||
{
|
||||
tweak[0] & 0xFFFFFFFFu,
|
||||
(tweak[0] >> 32) & 0xFFFFFFFFu,
|
||||
tweak[1] & 0xFFFFFFFFu
|
||||
};
|
||||
ulong num = (ulong)advance;
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
num = (array[i] = num + array[i]) >> 32;
|
||||
}
|
||||
tweak[0] = ((array[1] & 0xFFFFFFFFu) << 32) | (array[0] & 0xFFFFFFFFu);
|
||||
tweak[1] = (tweak[1] & 0xFFFFFFFF00000000uL) | (array[2] & 0xFFFFFFFFu);
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong num2 = tweak[0];
|
||||
num2 += (uint)advance;
|
||||
tweak[0] = num2;
|
||||
if (num2 > 18446744069414584320uL)
|
||||
{
|
||||
extendedPosition = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ulong[] GetWords()
|
||||
{
|
||||
return tweak;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Type + " first: " + First + ", final: " + Final;
|
||||
}
|
||||
}
|
||||
|
||||
private class UBI
|
||||
{
|
||||
private readonly UbiTweak tweak = new UbiTweak();
|
||||
|
||||
private readonly SkeinEngine engine;
|
||||
|
||||
private byte[] currentBlock;
|
||||
|
||||
private int currentOffset;
|
||||
|
||||
private ulong[] message;
|
||||
|
||||
public UBI(SkeinEngine engine, int blockSize)
|
||||
{
|
||||
this.engine = engine;
|
||||
currentBlock = new byte[blockSize];
|
||||
message = new ulong[currentBlock.Length / 8];
|
||||
}
|
||||
|
||||
public void Reset(UBI ubi)
|
||||
{
|
||||
currentBlock = Arrays.Clone(ubi.currentBlock, currentBlock);
|
||||
currentOffset = ubi.currentOffset;
|
||||
message = Arrays.Clone(ubi.message, message);
|
||||
tweak.Reset(ubi.tweak);
|
||||
}
|
||||
|
||||
public void Reset(int type)
|
||||
{
|
||||
tweak.Reset();
|
||||
tweak.Type = (uint)type;
|
||||
currentOffset = 0;
|
||||
}
|
||||
|
||||
public void Update(byte[] value, int offset, int len, ulong[] output)
|
||||
{
|
||||
int num = 0;
|
||||
while (len > num)
|
||||
{
|
||||
if (currentOffset == currentBlock.Length)
|
||||
{
|
||||
ProcessBlock(output);
|
||||
tweak.First = false;
|
||||
currentOffset = 0;
|
||||
}
|
||||
int num2 = System.Math.Min(len - num, currentBlock.Length - currentOffset);
|
||||
Array.Copy(value, offset + num, currentBlock, currentOffset, num2);
|
||||
num += num2;
|
||||
currentOffset += num2;
|
||||
tweak.AdvancePosition(num2);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessBlock(ulong[] output)
|
||||
{
|
||||
engine.threefish.Init(forEncryption: true, engine.chain, tweak.GetWords());
|
||||
for (int i = 0; i < message.Length; i++)
|
||||
{
|
||||
message[i] = ThreefishEngine.BytesToWord(currentBlock, i * 8);
|
||||
}
|
||||
engine.threefish.ProcessBlock(message, output);
|
||||
for (int j = 0; j < output.Length; j++)
|
||||
{
|
||||
ulong[] array2;
|
||||
ulong[] array = (array2 = output);
|
||||
int num = j;
|
||||
nint num2 = num;
|
||||
array[num] = array2[num2] ^ message[j];
|
||||
}
|
||||
}
|
||||
|
||||
public void DoFinal(ulong[] output)
|
||||
{
|
||||
for (int i = currentOffset; i < currentBlock.Length; i++)
|
||||
{
|
||||
currentBlock[i] = 0;
|
||||
}
|
||||
tweak.Final = true;
|
||||
ProcessBlock(output);
|
||||
}
|
||||
}
|
||||
|
||||
public const int SKEIN_256 = 256;
|
||||
|
||||
public const int SKEIN_512 = 512;
|
||||
|
||||
public const int SKEIN_1024 = 1024;
|
||||
|
||||
private const int PARAM_TYPE_KEY = 0;
|
||||
|
||||
private const int PARAM_TYPE_CONFIG = 4;
|
||||
|
||||
private const int PARAM_TYPE_MESSAGE = 48;
|
||||
|
||||
private const int PARAM_TYPE_OUTPUT = 63;
|
||||
|
||||
private static readonly IDictionary INITIAL_STATES;
|
||||
|
||||
private readonly ThreefishEngine threefish;
|
||||
|
||||
private readonly int outputSizeBytes;
|
||||
|
||||
private ulong[] chain;
|
||||
|
||||
private ulong[] initialState;
|
||||
|
||||
private byte[] key;
|
||||
|
||||
private Parameter[] preMessageParameters;
|
||||
|
||||
private Parameter[] postMessageParameters;
|
||||
|
||||
private readonly UBI ubi;
|
||||
|
||||
private readonly byte[] singleByte = new byte[1];
|
||||
|
||||
public int OutputSize => outputSizeBytes;
|
||||
|
||||
public int BlockSize => threefish.GetBlockSize();
|
||||
|
||||
static SkeinEngine()
|
||||
{
|
||||
INITIAL_STATES = Platform.CreateHashtable();
|
||||
InitialState(256, 128, new ulong[4] { 16217771249220022880uL, 9817190399063458076uL, 1155188648486244218uL, 14769517481627992514uL });
|
||||
InitialState(256, 160, new ulong[4] { 1450197650740764312uL, 3081844928540042640uL, 15310647011875280446uL, 3301952811952417661uL });
|
||||
InitialState(256, 224, new ulong[4] { 14270089230798940683uL, 9758551101254474012uL, 11082101768697755780uL, 4056579644589979102uL });
|
||||
InitialState(256, 256, new ulong[4] { 18202890402666165321uL, 3443677322885453875uL, 12915131351309911055uL, 7662005193972177513uL });
|
||||
InitialState(512, 128, new ulong[8] { 12158729379475595090uL, 2204638249859346602uL, 3502419045458743507uL, 13617680570268287068uL, 983504137758028059uL, 1880512238245786339uL, 11730851291495443074uL, 7602827311880509485uL });
|
||||
InitialState(512, 160, new ulong[8] { 2934123928682216849uL, 14047033351726823311uL, 1684584802963255058uL, 5744138295201861711uL, 2444857010922934358uL, 15638910433986703544uL, 13325156239043941114uL, 118355523173251694uL });
|
||||
InitialState(512, 224, new ulong[8] { 14758403053642543652uL, 14674518637417806319uL, 10145881904771976036uL, 4146387520469897396uL, 1106145742801415120uL, 7455425944880474941uL, 11095680972475339753uL, 11397762726744039159uL });
|
||||
InitialState(512, 384, new ulong[8] { 11814849197074935647uL, 12753905853581818532uL, 11346781217370868990uL, 15535391162178797018uL, 2000907093792408677uL, 9140007292425499655uL, 6093301768906360022uL, 2769176472213098488uL });
|
||||
InitialState(512, 512, new ulong[8] { 5261240102383538638uL, 978932832955457283uL, 10363226125605772238uL, 11107378794354519217uL, 6752626034097301424uL, 16915020251879818228uL, 11029617608758768931uL, 12544957130904423475uL });
|
||||
}
|
||||
|
||||
private static void InitialState(int blockSize, int outputSize, ulong[] state)
|
||||
{
|
||||
INITIAL_STATES.Add(VariantIdentifier(blockSize / 8, outputSize / 8), state);
|
||||
}
|
||||
|
||||
private static int VariantIdentifier(int blockSizeBytes, int outputSizeBytes)
|
||||
{
|
||||
return (outputSizeBytes << 16) | blockSizeBytes;
|
||||
}
|
||||
|
||||
public SkeinEngine(int blockSizeBits, int outputSizeBits)
|
||||
{
|
||||
if (outputSizeBits % 8 != 0)
|
||||
{
|
||||
throw new ArgumentException("Output size must be a multiple of 8 bits. :" + outputSizeBits);
|
||||
}
|
||||
outputSizeBytes = outputSizeBits / 8;
|
||||
threefish = new ThreefishEngine(blockSizeBits);
|
||||
ubi = new UBI(this, threefish.GetBlockSize());
|
||||
}
|
||||
|
||||
public SkeinEngine(SkeinEngine engine)
|
||||
: this(engine.BlockSize * 8, engine.OutputSize * 8)
|
||||
{
|
||||
CopyIn(engine);
|
||||
}
|
||||
|
||||
private void CopyIn(SkeinEngine engine)
|
||||
{
|
||||
ubi.Reset(engine.ubi);
|
||||
chain = Arrays.Clone(engine.chain, chain);
|
||||
initialState = Arrays.Clone(engine.initialState, initialState);
|
||||
key = Arrays.Clone(engine.key, key);
|
||||
preMessageParameters = Clone(engine.preMessageParameters, preMessageParameters);
|
||||
postMessageParameters = Clone(engine.postMessageParameters, postMessageParameters);
|
||||
}
|
||||
|
||||
private static Parameter[] Clone(Parameter[] data, Parameter[] existing)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (existing == null || existing.Length != data.Length)
|
||||
{
|
||||
existing = new Parameter[data.Length];
|
||||
}
|
||||
Array.Copy(data, 0, existing, 0, existing.Length);
|
||||
return existing;
|
||||
}
|
||||
|
||||
public IMemoable Copy()
|
||||
{
|
||||
return new SkeinEngine(this);
|
||||
}
|
||||
|
||||
public void Reset(IMemoable other)
|
||||
{
|
||||
SkeinEngine skeinEngine = (SkeinEngine)other;
|
||||
if (BlockSize != skeinEngine.BlockSize || outputSizeBytes != skeinEngine.outputSizeBytes)
|
||||
{
|
||||
throw new MemoableResetException("Incompatible parameters in provided SkeinEngine.");
|
||||
}
|
||||
CopyIn(skeinEngine);
|
||||
}
|
||||
|
||||
public void Init(SkeinParameters parameters)
|
||||
{
|
||||
chain = null;
|
||||
key = null;
|
||||
preMessageParameters = null;
|
||||
postMessageParameters = null;
|
||||
if (parameters != null)
|
||||
{
|
||||
byte[] array = parameters.GetKey();
|
||||
if (array.Length < 16)
|
||||
{
|
||||
throw new ArgumentException("Skein key must be at least 128 bits.");
|
||||
}
|
||||
InitParams(parameters.GetParameters());
|
||||
}
|
||||
CreateInitialState();
|
||||
UbiInit(48);
|
||||
}
|
||||
|
||||
private void InitParams(IDictionary parameters)
|
||||
{
|
||||
IEnumerator enumerator = parameters.Keys.GetEnumerator();
|
||||
IList list = Platform.CreateArrayList();
|
||||
IList list2 = Platform.CreateArrayList();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
int num = (int)enumerator.Current;
|
||||
byte[] value = (byte[])parameters[num];
|
||||
if (num == 0)
|
||||
{
|
||||
key = value;
|
||||
}
|
||||
else if (num < 48)
|
||||
{
|
||||
list.Add(new Parameter(num, value));
|
||||
}
|
||||
else
|
||||
{
|
||||
list2.Add(new Parameter(num, value));
|
||||
}
|
||||
}
|
||||
preMessageParameters = new Parameter[list.Count];
|
||||
list.CopyTo(preMessageParameters, 0);
|
||||
Array.Sort((Array)preMessageParameters);
|
||||
postMessageParameters = new Parameter[list2.Count];
|
||||
list2.CopyTo(postMessageParameters, 0);
|
||||
Array.Sort((Array)postMessageParameters);
|
||||
}
|
||||
|
||||
private void CreateInitialState()
|
||||
{
|
||||
ulong[] array = (ulong[])INITIAL_STATES[VariantIdentifier(BlockSize, OutputSize)];
|
||||
if (key == null && array != null)
|
||||
{
|
||||
chain = Arrays.Clone(array);
|
||||
}
|
||||
else
|
||||
{
|
||||
chain = new ulong[BlockSize / 8];
|
||||
if (key != null)
|
||||
{
|
||||
UbiComplete(0, key);
|
||||
}
|
||||
UbiComplete(4, new Configuration(outputSizeBytes * 8).Bytes);
|
||||
}
|
||||
if (preMessageParameters != null)
|
||||
{
|
||||
for (int i = 0; i < preMessageParameters.Length; i++)
|
||||
{
|
||||
Parameter parameter = preMessageParameters[i];
|
||||
UbiComplete(parameter.Type, parameter.Value);
|
||||
}
|
||||
}
|
||||
initialState = Arrays.Clone(chain);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Array.Copy(initialState, 0, chain, 0, chain.Length);
|
||||
UbiInit(48);
|
||||
}
|
||||
|
||||
private void UbiComplete(int type, byte[] value)
|
||||
{
|
||||
UbiInit(type);
|
||||
ubi.Update(value, 0, value.Length, chain);
|
||||
UbiFinal();
|
||||
}
|
||||
|
||||
private void UbiInit(int type)
|
||||
{
|
||||
ubi.Reset(type);
|
||||
}
|
||||
|
||||
private void UbiFinal()
|
||||
{
|
||||
ubi.DoFinal(chain);
|
||||
}
|
||||
|
||||
private void CheckInitialised()
|
||||
{
|
||||
if (ubi == null)
|
||||
{
|
||||
throw new ArgumentException("Skein engine is not initialised.");
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(byte inByte)
|
||||
{
|
||||
singleByte[0] = inByte;
|
||||
Update(singleByte, 0, 1);
|
||||
}
|
||||
|
||||
public void Update(byte[] inBytes, int inOff, int len)
|
||||
{
|
||||
CheckInitialised();
|
||||
ubi.Update(inBytes, inOff, len, chain);
|
||||
}
|
||||
|
||||
public int DoFinal(byte[] outBytes, int outOff)
|
||||
{
|
||||
CheckInitialised();
|
||||
if (outBytes.Length < outOff + outputSizeBytes)
|
||||
{
|
||||
throw new DataLengthException("Output buffer is too short to hold output");
|
||||
}
|
||||
UbiFinal();
|
||||
if (postMessageParameters != null)
|
||||
{
|
||||
for (int i = 0; i < postMessageParameters.Length; i++)
|
||||
{
|
||||
Parameter parameter = postMessageParameters[i];
|
||||
UbiComplete(parameter.Type, parameter.Value);
|
||||
}
|
||||
}
|
||||
int blockSize = BlockSize;
|
||||
int num = (outputSizeBytes + blockSize - 1) / blockSize;
|
||||
for (int j = 0; j < num; j++)
|
||||
{
|
||||
int outputBytes = System.Math.Min(blockSize, outputSizeBytes - j * blockSize);
|
||||
Output((ulong)j, outBytes, outOff + j * blockSize, outputBytes);
|
||||
}
|
||||
Reset();
|
||||
return outputSizeBytes;
|
||||
}
|
||||
|
||||
private void Output(ulong outputSequence, byte[] outBytes, int outOff, int outputBytes)
|
||||
{
|
||||
byte[] array = new byte[8];
|
||||
ThreefishEngine.WordToBytes(outputSequence, array, 0);
|
||||
ulong[] array2 = new ulong[chain.Length];
|
||||
UbiInit(63);
|
||||
ubi.Update(array, 0, array.Length, array2);
|
||||
ubi.DoFinal(array2);
|
||||
int num = (outputBytes + 8 - 1) / 8;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
int num2 = System.Math.Min(8, outputBytes - i * 8);
|
||||
if (num2 == 8)
|
||||
{
|
||||
ThreefishEngine.WordToBytes(array2[i], outBytes, outOff + i * 8);
|
||||
continue;
|
||||
}
|
||||
ThreefishEngine.WordToBytes(array2[i], array, 0);
|
||||
Array.Copy(array, 0, outBytes, outOff + i * 8, num2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public class TigerDigest : IDigest, IMemoable
|
||||
{
|
||||
private const int MyByteLength = 64;
|
||||
|
||||
private const int DigestLength = 24;
|
||||
|
||||
private static readonly long[] t1 = new long[256]
|
||||
{
|
||||
192161084409973854L, -6034178070669973268L, 8272369121297300691L, 7854730284916899642L, -3631738584360316525L, 8463286011307239906L, -5664346993730092093L, 5082381371487377520L, -1536603760329757466L, -4232985935611735204L,
|
||||
5541490850629862524L, 766444128913191948L, 1204553577021685498L, -4121719295987045526L, 1401289229890216703L, 1893918052108309022L, 5461170853188208586L, 2807403890869420487L, -8822417684582283338L, 5699452412975025298L,
|
||||
-2914262034798377397L, -8199292901130911363L, 7624427211800470465L, -5330070367527189138L, 9043806901924967914L, 7231827479902542914L, -4667804575905660192L, 6875646691050945796L, -954047427515838778L, 7786398710221814956L,
|
||||
8167597339425066981L, 1830707105885056415L, -192929137551915557L, -4000909680243679221L, -8790383730744944306L, -6559119868654993229L, -8046943608939121133L, -2635222011098072079L, 1783120314242633559L, 248005612187258982L,
|
||||
7688500634458409525L, -799055769434250085L, 8591138587399736033L, -2813706756098348539L, -4803442773389201549L, 5042603696143252264L, 2053990370701680515L, -8434990628116389527L, 3741955435321465241L, 4334407786093429776L,
|
||||
-5399798173115342087L, 1449859124008718907L, -259597992345095852L, -2299784421946890745L, -8624947886301142065L, -7850603641235491331L, 3847074041673952000L, 4649400157396704725L, -4273499526689310132L, -3840742565288711634L,
|
||||
2909491499011162061L, 4458122598401901638L, 7071481730398905774L, 6725294491764459774L, -6201551736110472662L, -4372530048007926361L, 1226483701329067140L, -2522035007050864557L, -3676115808446124170L, -4975751036383735295L,
|
||||
-1831728144282101387L, -7732658914112356844L, 479582384021555544L, 8040612334407127321L, -2798227069691230528L, -1334228551670664750L, 8751740296797632830L, 6603430683508552489L, 8942924799792477540L, 3573742753214737511L,
|
||||
-2419519573825602302L, 6349030933445924429L, -2501945979441900175L, -6177453506703404958L, -7885857697280165792L, 5194369709296555225L, 7174555471952375656L, 7982812746821821468L, -8707669106532426453L, 3232013613859041307L,
|
||||
-5747376245209101971L, -2231459388012946321L, 3112410413624570453L, -2336602742119691332L, 6658792778814911418L, 6126246269502162262L, -6070952467612144753L, 4721051187472420532L, -5533619424469951182L, -4853025588084287359L,
|
||||
2663576151211431276L, 928112258657309258L, 5664920977038299994L, 2704699625848084345L, 2312925355491498803L, -528812816973409076L, 2964761606854114992L, 4148718494125202372L, 4082542483235864459L, 5171535286737311423L,
|
||||
2166137813939512309L, 8844224567096109974L, -6373247044080797239L, -8133614489572350707L, 7053919794999990929L, 5576291611870337032L, -1374825740467639573L, -734453569254161202L, -705972172313107935L, -6688726126811769884L,
|
||||
-7468621655906046812L, -3527580439205474383L, -6956282119872554589L, -6281089153129775081L, 853355433004222246L, -1924221946255713479L, 2124075034376372323L, 5881355904936746717L, 1033318428544969251L, 1692585388818821524L,
|
||||
-1245985052454466526L, 1107424405919510210L, -9211670503851965599L, -5975256720516651978L, 963191604767572015L, 4506934758573727688L, -6511972687387035778L, -6714534832456272315L, 7421261837586505858L, 3318186242040429129L,
|
||||
-4402061108394378299L, 1910808081503L, 4771413979138012118L, -3357965141731676491L, -6811660122601107496L, 3247421105326436348L, -1009844908434318049L, 8353265116968520410L, -5881406294935394735L, -7574869783018555510L,
|
||||
6528592316425799439L, -3049672598698961616L, -3303981966096002009L, 7320455443630736945L, -7351974990356818097L, 2539802313181221187L, -7307523792611951465L, 6084456898448652712L, 1615327116689102472L, 8126548348642832045L,
|
||||
-1094214848903295726L, 6320848846662414801L, -1163799684465161365L, 3439926484095136410L, -7218302546559918104L, 4583261464596863494L, 5278432013075676693L, 672210957064462075L, -5420889727701263133L, -3948047341652367807L,
|
||||
3753742208681096767L, -5185515461782971584L, -460252340867529358L, 111470777923844445L, 1951374535466601971L, -8875343681432095955L, -4493729248843343338L, 4830799035278983864L, -5224728565293047538L, 6842302225500364445L,
|
||||
-7111193868311747516L, -2729919277420993032L, -5582278241003401657L, -126421769187551098L, -4035721366655415313L, -1986169280154305277L, 3977519900599801820L, 9148781857317432677L, 6468933130968205401L, 8516219711084257782L,
|
||||
1539015908620793624L, 7527026033758878374L, -1647949680688450337L, 3088835283432281588L, 3651919061693825289L, -8985256062000155568L, -423165018983337331L, -7032056788937726985L, 308165109378616703L, 8884692927086426203L,
|
||||
2438838841395254149L, -3550173447755953499L, 2823241734971430590L, 3896218688877146334L, 393786506094771122L, -3117973570538943511L, -7973569017697024389L, -8368763565314219996L, 6934559736714979565L, -589348163057397487L,
|
||||
-7554853961030558080L, -6878676038788161577L, -3798065817641571893L, -9101961441510934879L, -4559443103670756675L, -7665374195348870830L, -8336074436196531783L, 4236391428300945648L, 555138268555536248L, 5351590591369890935L,
|
||||
4306521946498657944L, -7151482210676895604L, 4901816398460471456L, -9033789479800328823L, 7485939926152528684L, -5105994143555176462L, 6245128712556390173L, -4718679834244078161L, -325273111308121687L, 7772052866533484500L,
|
||||
639373189613950878L, 2515940555210603828L, -2058685867725021174L, 9187445612742136046L, -5771987833248487369L, -2125811817212952004L, -3204735567712096048L, -3393897870002714342L, 1313621308117380133L, 3526835097255131285L,
|
||||
-4953033604042954265L, 8704164972314360376L, -920137909863202916L, 5969067443919232116L, 5791404459833380522L, -1682712826007985785L, 6001456072058810555L, -8273861206301250160L, 2241175407069758350L, -2962551490920225208L,
|
||||
8359644330926224055L, -8523485772611717717L, -5183265553382750L, -1789270636298447811L, -6471656072873752544L, -1458735953920612486L
|
||||
};
|
||||
|
||||
private static readonly long[] t2 = new long[256]
|
||||
{
|
||||
-1826563305001377480L, -5358963986493047656L, 6213947727727520144L, 5496303794639560149L, -2795981259149962188L, 642450021946863605L, -2925749420550550287L, -4252676236223476327L, -2372897249057438062L, -2455723000952046826L,
|
||||
8011611286970690052L, 5372247966639775667L, -6490268738015937967L, -265982677241022690L, -1711898199407229911L, -2553549223344005918L, -3655427155680827379L, 1788379855404599063L, 3792259505844355329L, 857793142685420274L,
|
||||
2176386753693503798L, -2281187609587102471L, -12877901320348396L, 6070247714570225101L, 7358743242340641331L, -8703516059324417162L, 1522910625901990663L, -2134847759353728262L, 5235630359010597374L, -5774648161970196758L,
|
||||
277273466943670671L, 3580831169916433691L, -1032406685548103719L, 4657750985732713388L, 1177149711660596421L, 8685721698255572101L, -3227632359902186326L, -6349410231276355429L, -4809500581665772080L, -7923309769729008016L,
|
||||
-6726740716384263588L, -4587792071496920925L, -658271017113840853L, 3834592178494549117L, -3853851402329989932L, -8865288174312808228L, 8774750272303345432L, -8428026360225307604L, -3404183201405868250L, 6519077675840655372L,
|
||||
1009372798613472243L, -4504928615151511518L, 7670504156571609794L, -9068448121725124008L, 7481699948221361317L, 2131352009749933493L, 7854556580946198495L, 5848046147829288198L, 6811751916476253359L, -635956774299390418L,
|
||||
-4737535235939835750L, -1614809042241653147L, 8245611441321613668L, 8087057586628171618L, 5058061449640751271L, -5151918184365513026L, 7212395796113148780L, 8872633840395976086L, 8602726521519041395L, -5885490816789515276L,
|
||||
6042660761688602872L, 1642367900117110883L, 25924001596622557L, 7531865058110106323L, 4223621278438660202L, 3926684511422013614L, -2064363959953346089L, 5939130201053773422L, 8312208923375399755L, 5278156969609628584L,
|
||||
-5712322089306707131L, 3610014133393185213L, -8850224129823554669L, -7989215126425784091L, 7953444341930717599L, -5072589324995998940L, -3677986556148923193L, 5127306049615917691L, 9121210965518562125L, 8462056263389103903L,
|
||||
-743704981880018871L, 5658738406708581754L, 3084862250275496789L, -2839477530259368618L, -3966384508771725354L, -3487534071112132806L, -123994483119243460L, -1345606558677941971L, -8999779576894164844L, -4191785782441631580L,
|
||||
1116769798908306816L, 1871732813531574911L, -5639228995346094013L, 2050857069623328786L, 942713319182180155L, -8555767913901511542L, -1938713800388260250L, 7028952989422544417L, 9018945159409650955L, -9098571702620193189L,
|
||||
512456053301416255L, -4053543709501018729L, -4330900206871259305L, -1512795427272957464L, -3102984968199159270L, -7389706432295929941L, -6638196300801425917L, -7112719166685012944L, 4569666897377300404L, -7151449437793514816L,
|
||||
4462677101358564049L, 3679240545963649394L, -4129112553160565951L, 776201060342576796L, -1202834617519492059L, -842133208882402856L, -8445297248460022090L, 3458390008116962295L, -8107400727032609416L, 6618311662604863029L,
|
||||
4790267690900900096L, 1716087693007726108L, 4148457837926911568L, -5418957485852076861L, 8968309666649857421L, -2611360075161572255L, 6968029403465067289L, -3584187592496365262L, 500987773930853904L, -8168172799095912208L,
|
||||
2355660670689429871L, 3178293543037890097L, -5583593033549110520L, -6297125087914569009L, 894835714693979080L, -5305826774090122525L, -348051181029808153L, 352461093517089771L, 5441805419015688358L, -3049381223523647492L,
|
||||
3501129463520285556L, -4980126173351398283L, -8303518980934164731L, -7446347735086057113L, 2615208954064994172L, -522603252265687058L, 2237558221535645089L, -3911919600557704777L, -5210711461681408094L, 7102368496127332321L,
|
||||
-7719366717024918019L, 399232473491847935L, 7140013836546489399L, -8234741283244511424L, -2231392863125672626L, -7060197492102713059L, 5038446221635409553L, 6294769326316815049L, -387802090031244907L, -3350046130045840024L,
|
||||
-2666808022981539793L, -6161723600240465717L, 2783168786742146440L, 1986639352536355296L, -1988727118208302602L, 8799325730492140254L, 7305467695957075406L, 2551364576700533681L, -6081001307066006598L, -4889804522683628146L,
|
||||
-7324859595388608820L, -6885748294050442179L, 5760535140236403614L, 1501217875009212803L, -1291632093432900094L, -7706153952057205239L, 6454505253869455699L, 4319683495060363885L, -6244922308576078969L, -6818767823778904188L,
|
||||
2960027307368769952L, 8570410701452901115L, 160427886842421800L, -4969938860820756853L, -4627442630994782527L, -3285648034072744413L, -7606118162332863056L, 6176075057452006273L, 7582622308322968760L, 6649763778434249567L,
|
||||
-183456705028906550L, 2699628156079216836L, -1767231947251866451L, 2945653313023238585L, 2813841150172635667L, 8163160757531991904L, -7212422464109809801L, -5924618728816493121L, 649720531103423106L, 6394120152722619742L,
|
||||
-934965811117111118L, 4753049982369101610L, 2408845162401379802L, 1253140645631747605L, -7799048643966905049L, -1584266091164108743L, -456002869645138839L, 8367255505928917714L, 91400768704631494L, -4464375255980341934L,
|
||||
1938401838693046941L, -7520293791609324052L, -8636597607271566304L, 3990523136699180870L, 7731749711829208666L, 4875740361372990282L, 9173201802070489451L, 7834799413446679311L, -6433392137177717442L, 3325271250982575439L,
|
||||
-8730608807451740020L, -2389358865336045484L, -9209652622095187875L, 4359958813756723849L, 4539467735137059035L, -5508531677782308793L, 1312945880979454078L, -947428475416758718L, 4958176066159770025L, 1374196081931091686L,
|
||||
-6918434684938959032L, -1095184559281703237L, -1411469442470588444L, 3145683508650593868L, -6039522865352658195L, -3804467173852034031L, -6563710254104815428L, 6868326517302426863L, 6758043032196830276L, 5827167051130463242L,
|
||||
4074828688890126937L, 3293442170241026694L, -8065760984084440343L, 5618223731912049521L, -3014545685365689991L, 2520538699101199374L
|
||||
};
|
||||
|
||||
private static readonly long[] t3 = new long[256]
|
||||
{
|
||||
-819712100864953445L, 5224129141031473793L, -1683494792012715969L, 3214246200928423523L, -2720183745931134014L, 3432136347919366758L, -6844377996819786796L, -4697838837464539535L, -3480123136110369641L, -5257202687841710057L,
|
||||
-3160671586143389472L, -8143604544638974599L, -7582212342885995579L, 7399204607179264370L, 2410740665327626235L, -5531319028708868287L, -1132011872800708955L, -8244108713684067595L, -8100030830173699490L, -865042824158552761L,
|
||||
-1406263208487841571L, -743744098937138031L, -7255025749313877870L, 5293216666010209768L, -6686350151342941087L, 505172698323928814L, -8504163865352868456L, -6039198373597746942L, 2102395425312436973L, -1480681786698906867L,
|
||||
6364975572501938982L, -7035658141633266754L, -8022507636838873565L, -4480433668109774745L, 2328871106231838244L, 1378680973804076623L, -3586772320324138908L, -2755027987269747529L, 7519553577929664460L, 460638964809724379L,
|
||||
-99820877092259348L, 6562793443469826132L, 1580997072160885165L, 859005579845670993L, -3058956174016989192L, -3379814835910611228L, -3936971176641920257L, -8723858077265400670L, 3784640730692549981L, -2514946515147142870L,
|
||||
-718211188705137671L, 5877026246039211124L, -8623573777109189598L, -6383628662057423219L, 4036482174343220762L, -6451625591996463702L, -5974472282720051687L, -4119613249555124729L, -4204805774663870152L, 1637614953354483776L,
|
||||
1768420517056302872L, -6063481615036972513L, 4469119677486524438L, 6862084742702193339L, 2666591392741323510L, 1958911907595193257L, 2078226524874004819L, 9182514826368667184L, -5667455777910095811L, -6961112304229951815L,
|
||||
7984583406477441100L, 5152724216922222472L, -2011927023009527807L, -212234053999724107L, 4838452819165657451L, -8437636414480207278L, -4364095106444861094L, -8843563141488759799L, -952547977505311611L, 7192165871822020282L,
|
||||
-8957588412064574366L, 4293149567017494192L, 6266031685674981260L, 3297360663327026118L, -7424220229153493459L, 1848411117523063487L, 4803542876947788811L, -6514007507455064743L, 3918859449562378630L, 7730455268829558643L,
|
||||
2300310138214025757L, 5073098731442674389L, -1867327214174801803L, -5119713925479725192L, 2481833961960165662L, 3483465760582650171L, -3799159280037322961L, -2614176868807805682L, 3683901813415452623L, -6586240258798896426L,
|
||||
-6280196637815307286L, -6878770741467980580L, -8649528727307138543L, 1263269478536931145L, -7419991789716909164L, -5769815365846261236L, 7280608515770959015L, 7790930297845911262L, -5059374975740702796L, -6705059931318638429L,
|
||||
8900403996915095151L, 8816891275549542045L, -476483339080012016L, -1232282160203339243L, 3119849171172694992L, 7662494604586420558L, 149203013753700084L, 5530308158539891708L, 4143436129840869576L, -3411623459852687238L,
|
||||
-1026352410626214551L, -8324492521276276327L, 6707891355510602429L, 5715986277202524800L, -393206988093480487L, 4600951196636466039L, -4593511655318796512L, 9065747437067558111L, -8901650410637853864L, 2592076422926394627L,
|
||||
228032410479194937L, 6667480117540136779L, 588648581915253038L, -2336950474993240516L, 3634608293302267354L, 1202024298738736502L, 6299068367672194603L, 1932346445954743183L, 7573861666572117031L, -61815566784892605L,
|
||||
3549459440654955014L, 8158286332358861718L, -7670372790848096527L, -515956617046547146L, -3963219078081420846L, 8464707252757847009L, 397230465775035974L, -4957137534187579283L, 675316509725923312L, 2628613740627889320L,
|
||||
-2532211618462009391L, 5345232712238813773L, -4776658006885916949L, 3062009004852183467L, -2381228231588757251L, 74184876899443393L, -1882978417976974457L, 9131956796466541322L, 8604540880985875509L, 22099178757704754L,
|
||||
-1755823172185693422L, -7115222264497037070L, 2945473010562318822L, -3264392033958139096L, 2789803412788518275L, -5023951698716947073L, -2879016497062593138L, 1017933909609308228L, -2136777458168640962L, 8230916861376446652L,
|
||||
-4050239832011059757L, 8983610917420146076L, 8543542228473779244L, 1721876046845854392L, -2252284190053484385L, 5559864569757380000L, 4937681992884682033L, -5441254327629638811L, -9066842030330493037L, 5670390740934713304L,
|
||||
2219071780988037499L, 7008521987288882964L, 6028345117330418825L, -7500176903196747008L, 7071075452076274675L, -1604175089662029304L, 1445978213955986826L, -7979034942316814172L, 951333080223670799L, 6099155138413436065L,
|
||||
-4305900099056973791L, -6236769450809946705L, -2912898243239114769L, -2065740773420267803L, -3827177893057145596L, 1340472571717533606L, -3648363291767490877L, -5756567784146095673L, 4461163794677446508L, -5848717005041324781L,
|
||||
3341940384398866564L, -4882598382547103543L, 3829921822543532494L, 899996630714791418L, 6478536468284266291L, 2994597028103565543L, 6124895672834828926L, -8376542604899771579L, -4412652237062246342L, -7724700941812371646L,
|
||||
728866099714851926L, 339635816873858970L, -1153572816294167456L, -592215260546165052L, -7150089944179092253L, 8700134485486622004L, -5552633324984327062L, -1298517758115136471L, 8749621007278605595L, -6133576477421907076L,
|
||||
4199955888901663150L, -5341432795218012713L, -239890188217778377L, 8106773277103211697L, -2229320058079270256L, 5930619164422717276L, 4368075505682949467L, 4623369983466747106L, 8403817438537116875L, -5327756068839670070L,
|
||||
1151085119119418028L, 6933250016240323664L, 6814675599201764477L, -2995490164984896514L, 5778917359701360712L, -7334472845550608018L, -9212347808668562614L, -7786744047088363785L, 4025584697920591189L, 5446500518121291045L,
|
||||
-7866665254384488512L, -352887593087136842L, 8290028954029701554L, -9087549732707247512L, 7234639242841923679L, 2860911103167493259L, -3716770017321781837L, 7444204691177324181L, 8012224255291120002L, 6549509778060988165L,
|
||||
-4656265058823564969L, -1532696805485516055L, 4993489137437819341L, 4727924503904151836L, -3180601338503688336L, 7858325008468642462L
|
||||
};
|
||||
|
||||
private static readonly long[] t4 = new long[256]
|
||||
{
|
||||
6561287832113134677L, 1893413629145602549L, -6205320776685678598L, 7334764389497132503L, 421942495471316930L, -9085229951450268347L, 5948965432456907277L, -6872877502453521409L, 4831763938021002582L, -4272888574428519313L,
|
||||
5678704711006605406L, 4536654317168965104L, 802439540090739142L, 1728614842704535657L, 7852250862810361152L, -2970083550513149273L, 6999787169451700297L, 327545298748531618L, -2764213178345403342L, 9213801181845131435L,
|
||||
-5950018878971805109L, -2186876610533351532L, -3100863505161590557L, -194921935069456237L, 2629011484744925146L, 679658461659738748L, -3068808746888436091L, 2845612796809381245L, -7722098226173915145L, 7273530125705028225L,
|
||||
4410076014410041819L, -2304212329100317967L, -45936371244098582L, -5712723046817425393L, 8922873767131958175L, -3382299200423854708L, -3236816455951139535L, -4036747678298392505L, 5226125132195873799L, 2940247444995640068L,
|
||||
-4418018165041970817L, 6671397049608501367L, 8821388386505911040L, -3580187736799586652L, -1447046360908978430L, 2147098610462912262L, -1956265881574637814L, -2856917834249223582L, 5141735866072457044L, 3265027362719053310L,
|
||||
-6450920645962515936L, 6017965846669640613L, 4287051124723328232L, 8655371236021312991L, -1156847972119148173L, 2365060307249772354L, 1630631832073154105L, 1828719980936758421L, 2674037562503248056L, -7295616781251116690L,
|
||||
-1363141094472255887L, 204405347605452144L, 5797523068258732423L, 8122903338174012641L, 8739821670855295734L, 961841682317282412L, 3487881148722869326L, -7995384159388863717L, 7665614591556333409L, -7831409025227614873L,
|
||||
-822907162794399275L, -1691135090558933875L, 3797048810173566205L, -2578904300750297763L, -3410711173298709536L, 577633178325057199L, -7379212936790430923L, -9035774148364232240L, 2754939666238358593L, 8444132705799138470L,
|
||||
-7894221632442939675L, 3065464070595795438L, -6610449357786147779L, 3184382822055416328L, 5740274767717360273L, 6179930651821454089L, -4826152258144849421L, 5115645765347262247L, 4602739923119569497L, -3465801151231271281L,
|
||||
-6359599548771540712L, -1926152657970122275L, -8468989295385802946L, -6500580506154635033L, 4125629484990072616L, -6834670983768857044L, -4845179353893108027L, 4230689665262407186L, -1849684427061896393L, 9047540561879224854L,
|
||||
1112218670439199625L, 8426162753992594376L, -5990769681480860131L, -2503790423972405993L, 4028912247909671416L, -409156412951274838L, -8377831951645714695L, -1152570669068554652L, -6327418252815316840L, -3725559206061705268L,
|
||||
1964465731879646024L, -2441760721249263597L, 6946242362685775318L, -3298979752616086841L, -7236283555339513389L, -1419193050620496778L, -93735727476260563L, -5905399081030416230L, 2507248404937789251L, 7581261321693772141L,
|
||||
-8836566033099333598L, 520172056875071564L, 3738403388662150470L, -2357506837776452040L, -5002739851233418934L, 930169001927683533L, 6889748805645999668L, -1031349426815687751L, 7941113837267854943L, -1243211017071393764L,
|
||||
-2154628650105719635L, 6332043450707792835L, 3386824618901547762L, 7130458179308482168L, 1271522336860346025L, -997034324337437613L, 4823850509807911142L, 3107332511049695348L, 5437793788182680416L, -8315628002795417155L,
|
||||
1494290439970088554L, -8609438560643873897L, -8207953325454440687L, -5432621302919780015L, 1159256241058966379L, 1026141471931805870L, -8215608786054685932L, -609691062749569444L, 7511556330643118785L, -3915792337899679783L,
|
||||
3932170512244996561L, 6834333685245251200L, 4355290964656419152L, 6487547078612259600L, 6267880520331323438L, -1545475867304599653L, 8190919284549556346L, 3366895789332200348L, 2444540809879438627L, 6459524513146455969L,
|
||||
4077716903750958194L, -6168929569432701476L, -6973483665415634802L, -5197441416039796052L, 7734160491610189202L, 7910254887717195099L, 3836881802794822270L, 8311228008842563790L, 730509642500215940L, -650400159804944995L,
|
||||
-5124223765383482859L, 3579688877020158541L, 8591780283260295173L, 5028082178778891827L, -498814760953987530L, -2709709455026140056L, 5487541034902828271L, 8530400576707172340L, -7604535187505054453L, -869656751120750718L,
|
||||
4656569414526204412L, 491061932033469878L, 8035458231926703496L, 137019260109594401L, 7421708309958176805L, 8223709417363553275L, 5401705824239018731L, -7162608250562934562L, 5308870500428712900L, -5508949737295341638L,
|
||||
1376856236535589493L, -5655908917112005032L, -7100674984259216372L, 1332977380922036690L, 3015788518022419172L, -6718854486329987908L, 6396540069380292132L, 2034188120276215631L, -1655134238111203034L, -509741179510489141L,
|
||||
3623665942510192329L, -9164935270648710301L, 1765784450088366494L, 5837777785993897047L, 1564973338399864744L, -2605395199060435761L, 4964475598524693274L, -5312043978489901415L, 6706291041494563888L, -789946623649963734L,
|
||||
-8091303779971721549L, 7456716478970921562L, -335263357675197259L, -8515348892102079999L, -7048796562806032069L, -233028078259189719L, 284725780453796946L, -3832073186324226638L, -4921235094493811069L, -5089093504863659344L,
|
||||
-5607539644671350465L, -8911681616096439592L, -4743899514573401058L, -7664321526450198170L, -4599281686566632149L, 2560491659082246267L, 8971180328015050686L, 2265540171276805379L, 6093561527083620308L, 12169565841013306L,
|
||||
9128413284208255679L, -4178722056535276608L, -8960148414521589626L, -4216952774774654326L, -5374970407177951367L, -6668788646589711127L, -2946910590031425822L, -8674853389405194592L, -7535980417822448849L, -6115357923114297461L,
|
||||
-8065837346967928004L, -7487037274649424496L, -2061373546992596293L, -5783192355322733388L, 7153300451507295513L, -8779488031786375734L, 2187906506867626476L, 5612681432830855607L, -4653220181978985551L, 4688837593722596333L,
|
||||
-3815667051463559517L, -1779743783662362556L, -3650491565905270770L, -4529053496248414107L, -4021111997381021802L, -4350414089199835873L
|
||||
};
|
||||
|
||||
private long a;
|
||||
|
||||
private long b;
|
||||
|
||||
private long c;
|
||||
|
||||
private long byteCount;
|
||||
|
||||
private byte[] Buffer = new byte[8];
|
||||
|
||||
private int bOff;
|
||||
|
||||
private long[] x = new long[8];
|
||||
|
||||
private int xOff;
|
||||
|
||||
public string AlgorithmName => "Tiger";
|
||||
|
||||
public TigerDigest()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public TigerDigest(TigerDigest t)
|
||||
{
|
||||
Reset(t);
|
||||
}
|
||||
|
||||
public int GetDigestSize()
|
||||
{
|
||||
return 24;
|
||||
}
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
private void ProcessWord(byte[] b, int off)
|
||||
{
|
||||
x[xOff++] = ((long)(b[off + 7] & 0xFF) << 56) | ((long)(b[off + 6] & 0xFF) << 48) | ((long)(b[off + 5] & 0xFF) << 40) | ((long)(b[off + 4] & 0xFF) << 32) | ((long)(b[off + 3] & 0xFF) << 24) | ((long)(b[off + 2] & 0xFF) << 16) | ((long)(b[off + 1] & 0xFF) << 8) | (uint)(b[off] & 0xFF);
|
||||
if (xOff == x.Length)
|
||||
{
|
||||
ProcessBlock();
|
||||
}
|
||||
bOff = 0;
|
||||
}
|
||||
|
||||
public void Update(byte input)
|
||||
{
|
||||
Buffer[bOff++] = input;
|
||||
if (bOff == Buffer.Length)
|
||||
{
|
||||
ProcessWord(Buffer, 0);
|
||||
}
|
||||
byteCount++;
|
||||
}
|
||||
|
||||
public void BlockUpdate(byte[] input, int inOff, int length)
|
||||
{
|
||||
while (bOff != 0 && length > 0)
|
||||
{
|
||||
Update(input[inOff]);
|
||||
inOff++;
|
||||
length--;
|
||||
}
|
||||
while (length > 8)
|
||||
{
|
||||
ProcessWord(input, inOff);
|
||||
inOff += 8;
|
||||
length -= 8;
|
||||
byteCount += 8L;
|
||||
}
|
||||
while (length > 0)
|
||||
{
|
||||
Update(input[inOff]);
|
||||
inOff++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
private void RoundABC(long x, long mul)
|
||||
{
|
||||
c ^= x;
|
||||
a -= t1[(int)c & 0xFF] ^ t2[(int)(c >> 16) & 0xFF] ^ t3[(int)(c >> 32) & 0xFF] ^ t4[(int)(c >> 48) & 0xFF];
|
||||
b += t4[(int)(c >> 8) & 0xFF] ^ t3[(int)(c >> 24) & 0xFF] ^ t2[(int)(c >> 40) & 0xFF] ^ t1[(int)(c >> 56) & 0xFF];
|
||||
b *= mul;
|
||||
}
|
||||
|
||||
private void RoundBCA(long x, long mul)
|
||||
{
|
||||
a ^= x;
|
||||
b -= t1[(int)a & 0xFF] ^ t2[(int)(a >> 16) & 0xFF] ^ t3[(int)(a >> 32) & 0xFF] ^ t4[(int)(a >> 48) & 0xFF];
|
||||
c += t4[(int)(a >> 8) & 0xFF] ^ t3[(int)(a >> 24) & 0xFF] ^ t2[(int)(a >> 40) & 0xFF] ^ t1[(int)(a >> 56) & 0xFF];
|
||||
c *= mul;
|
||||
}
|
||||
|
||||
private void RoundCAB(long x, long mul)
|
||||
{
|
||||
b ^= x;
|
||||
c -= t1[(int)b & 0xFF] ^ t2[(int)(b >> 16) & 0xFF] ^ t3[(int)(b >> 32) & 0xFF] ^ t4[(int)(b >> 48) & 0xFF];
|
||||
a += t4[(int)(b >> 8) & 0xFF] ^ t3[(int)(b >> 24) & 0xFF] ^ t2[(int)(b >> 40) & 0xFF] ^ t1[(int)(b >> 56) & 0xFF];
|
||||
a *= mul;
|
||||
}
|
||||
|
||||
private void KeySchedule()
|
||||
{
|
||||
long[] array;
|
||||
(array = x)[0] = array[0] - (x[7] ^ -6510615555426900571L);
|
||||
(array = x)[1] = array[1] ^ x[0];
|
||||
(array = x)[2] = array[2] + x[1];
|
||||
(array = x)[3] = array[3] - (x[2] ^ (~x[1] << 19));
|
||||
(array = x)[4] = array[4] ^ x[3];
|
||||
(array = x)[5] = array[5] + x[4];
|
||||
(array = x)[6] = array[6] - (x[5] ^ (~x[4] >>> 23));
|
||||
(array = x)[7] = array[7] ^ x[6];
|
||||
(array = x)[0] = array[0] + x[7];
|
||||
(array = x)[1] = array[1] - (x[0] ^ (~x[7] << 19));
|
||||
(array = x)[2] = array[2] ^ x[1];
|
||||
(array = x)[3] = array[3] + x[2];
|
||||
(array = x)[4] = array[4] - (x[3] ^ (~x[2] >>> 23));
|
||||
(array = x)[5] = array[5] ^ x[4];
|
||||
(array = x)[6] = array[6] + x[5];
|
||||
(array = x)[7] = array[7] - (x[6] ^ 0x123456789ABCDEFL);
|
||||
}
|
||||
|
||||
private void ProcessBlock()
|
||||
{
|
||||
long num = a;
|
||||
long num2 = b;
|
||||
long num3 = c;
|
||||
RoundABC(x[0], 5L);
|
||||
RoundBCA(x[1], 5L);
|
||||
RoundCAB(x[2], 5L);
|
||||
RoundABC(x[3], 5L);
|
||||
RoundBCA(x[4], 5L);
|
||||
RoundCAB(x[5], 5L);
|
||||
RoundABC(x[6], 5L);
|
||||
RoundBCA(x[7], 5L);
|
||||
KeySchedule();
|
||||
RoundCAB(x[0], 7L);
|
||||
RoundABC(x[1], 7L);
|
||||
RoundBCA(x[2], 7L);
|
||||
RoundCAB(x[3], 7L);
|
||||
RoundABC(x[4], 7L);
|
||||
RoundBCA(x[5], 7L);
|
||||
RoundCAB(x[6], 7L);
|
||||
RoundABC(x[7], 7L);
|
||||
KeySchedule();
|
||||
RoundBCA(x[0], 9L);
|
||||
RoundCAB(x[1], 9L);
|
||||
RoundABC(x[2], 9L);
|
||||
RoundBCA(x[3], 9L);
|
||||
RoundCAB(x[4], 9L);
|
||||
RoundABC(x[5], 9L);
|
||||
RoundBCA(x[6], 9L);
|
||||
RoundCAB(x[7], 9L);
|
||||
a ^= num;
|
||||
b -= num2;
|
||||
c += num3;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != x.Length; i++)
|
||||
{
|
||||
x[i] = 0L;
|
||||
}
|
||||
}
|
||||
|
||||
private void UnpackWord(long r, byte[] output, int outOff)
|
||||
{
|
||||
output[outOff + 7] = (byte)(r >> 56);
|
||||
output[outOff + 6] = (byte)(r >> 48);
|
||||
output[outOff + 5] = (byte)(r >> 40);
|
||||
output[outOff + 4] = (byte)(r >> 32);
|
||||
output[outOff + 3] = (byte)(r >> 24);
|
||||
output[outOff + 2] = (byte)(r >> 16);
|
||||
output[outOff + 1] = (byte)(r >> 8);
|
||||
output[outOff] = (byte)r;
|
||||
}
|
||||
|
||||
private void ProcessLength(long bitLength)
|
||||
{
|
||||
x[7] = bitLength;
|
||||
}
|
||||
|
||||
private void Finish()
|
||||
{
|
||||
long bitLength = byteCount << 3;
|
||||
Update(1);
|
||||
while (bOff != 0)
|
||||
{
|
||||
Update(0);
|
||||
}
|
||||
ProcessLength(bitLength);
|
||||
ProcessBlock();
|
||||
}
|
||||
|
||||
public int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
Finish();
|
||||
UnpackWord(a, output, outOff);
|
||||
UnpackWord(b, output, outOff + 8);
|
||||
UnpackWord(c, output, outOff + 16);
|
||||
Reset();
|
||||
return 24;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
a = 81985529216486895L;
|
||||
b = -81985529216486896L;
|
||||
c = -1110518062304271993L;
|
||||
xOff = 0;
|
||||
for (int i = 0; i != x.Length; i++)
|
||||
{
|
||||
x[i] = 0L;
|
||||
}
|
||||
bOff = 0;
|
||||
for (int j = 0; j != Buffer.Length; j++)
|
||||
{
|
||||
Buffer[j] = 0;
|
||||
}
|
||||
byteCount = 0L;
|
||||
}
|
||||
|
||||
public IMemoable Copy()
|
||||
{
|
||||
return new TigerDigest(this);
|
||||
}
|
||||
|
||||
public void Reset(IMemoable other)
|
||||
{
|
||||
TigerDigest tigerDigest = (TigerDigest)other;
|
||||
a = tigerDigest.a;
|
||||
b = tigerDigest.b;
|
||||
c = tigerDigest.c;
|
||||
Array.Copy(tigerDigest.x, 0, x, 0, tigerDigest.x.Length);
|
||||
xOff = tigerDigest.xOff;
|
||||
Array.Copy(tigerDigest.Buffer, 0, Buffer, 0, tigerDigest.Buffer.Length);
|
||||
bOff = tigerDigest.bOff;
|
||||
byteCount = tigerDigest.byteCount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
public sealed class WhirlpoolDigest : IDigest, IMemoable
|
||||
{
|
||||
private const int BYTE_LENGTH = 64;
|
||||
|
||||
private const int DIGEST_LENGTH_BYTES = 64;
|
||||
|
||||
private const int ROUNDS = 10;
|
||||
|
||||
private const int REDUCTION_POLYNOMIAL = 285;
|
||||
|
||||
private const int BITCOUNT_ARRAY_SIZE = 32;
|
||||
|
||||
private static readonly int[] SBOX;
|
||||
|
||||
private static readonly long[] C0;
|
||||
|
||||
private static readonly long[] C1;
|
||||
|
||||
private static readonly long[] C2;
|
||||
|
||||
private static readonly long[] C3;
|
||||
|
||||
private static readonly long[] C4;
|
||||
|
||||
private static readonly long[] C5;
|
||||
|
||||
private static readonly long[] C6;
|
||||
|
||||
private static readonly long[] C7;
|
||||
|
||||
private readonly long[] _rc = new long[11];
|
||||
|
||||
private static readonly short[] EIGHT;
|
||||
|
||||
private byte[] _buffer = new byte[64];
|
||||
|
||||
private int _bufferPos;
|
||||
|
||||
private short[] _bitCount = new short[32];
|
||||
|
||||
private long[] _hash = new long[8];
|
||||
|
||||
private long[] _K = new long[8];
|
||||
|
||||
private long[] _L = new long[8];
|
||||
|
||||
private long[] _block = new long[8];
|
||||
|
||||
private long[] _state = new long[8];
|
||||
|
||||
public string AlgorithmName => "Whirlpool";
|
||||
|
||||
static WhirlpoolDigest()
|
||||
{
|
||||
SBOX = new int[256]
|
||||
{
|
||||
24, 35, 198, 232, 135, 184, 1, 79, 54, 166,
|
||||
210, 245, 121, 111, 145, 82, 96, 188, 155, 142,
|
||||
163, 12, 123, 53, 29, 224, 215, 194, 46, 75,
|
||||
254, 87, 21, 119, 55, 229, 159, 240, 74, 218,
|
||||
88, 201, 41, 10, 177, 160, 107, 133, 189, 93,
|
||||
16, 244, 203, 62, 5, 103, 228, 39, 65, 139,
|
||||
167, 125, 149, 216, 251, 238, 124, 102, 221, 23,
|
||||
71, 158, 202, 45, 191, 7, 173, 90, 131, 51,
|
||||
99, 2, 170, 113, 200, 25, 73, 217, 242, 227,
|
||||
91, 136, 154, 38, 50, 176, 233, 15, 213, 128,
|
||||
190, 205, 52, 72, 255, 122, 144, 95, 32, 104,
|
||||
26, 174, 180, 84, 147, 34, 100, 241, 115, 18,
|
||||
64, 8, 195, 236, 219, 161, 141, 61, 151, 0,
|
||||
207, 43, 118, 130, 214, 27, 181, 175, 106, 80,
|
||||
69, 243, 48, 239, 63, 85, 162, 234, 101, 186,
|
||||
47, 192, 222, 28, 253, 77, 146, 117, 6, 138,
|
||||
178, 230, 14, 31, 98, 212, 168, 150, 249, 197,
|
||||
37, 89, 132, 114, 57, 76, 94, 120, 56, 140,
|
||||
209, 165, 226, 97, 179, 33, 156, 30, 67, 199,
|
||||
252, 4, 81, 153, 109, 13, 250, 223, 126, 36,
|
||||
59, 171, 206, 17, 143, 78, 183, 235, 60, 129,
|
||||
148, 247, 185, 19, 44, 211, 231, 110, 196, 3,
|
||||
86, 68, 127, 169, 42, 187, 193, 83, 220, 11,
|
||||
157, 108, 49, 116, 246, 70, 172, 137, 20, 225,
|
||||
22, 58, 105, 9, 112, 182, 208, 237, 204, 66,
|
||||
152, 164, 40, 92, 248, 134
|
||||
};
|
||||
C0 = new long[256];
|
||||
C1 = new long[256];
|
||||
C2 = new long[256];
|
||||
C3 = new long[256];
|
||||
C4 = new long[256];
|
||||
C5 = new long[256];
|
||||
C6 = new long[256];
|
||||
C7 = new long[256];
|
||||
EIGHT = new short[32];
|
||||
EIGHT[31] = 8;
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int num = SBOX[i];
|
||||
int num2 = maskWithReductionPolynomial(num << 1);
|
||||
int num3 = maskWithReductionPolynomial(num2 << 1);
|
||||
int num4 = num3 ^ num;
|
||||
int num5 = maskWithReductionPolynomial(num3 << 1);
|
||||
int num6 = num5 ^ num;
|
||||
C0[i] = packIntoLong(num, num, num3, num, num5, num4, num2, num6);
|
||||
C1[i] = packIntoLong(num6, num, num, num3, num, num5, num4, num2);
|
||||
C2[i] = packIntoLong(num2, num6, num, num, num3, num, num5, num4);
|
||||
C3[i] = packIntoLong(num4, num2, num6, num, num, num3, num, num5);
|
||||
C4[i] = packIntoLong(num5, num4, num2, num6, num, num, num3, num);
|
||||
C5[i] = packIntoLong(num, num5, num4, num2, num6, num, num, num3);
|
||||
C6[i] = packIntoLong(num3, num, num5, num4, num2, num6, num, num);
|
||||
C7[i] = packIntoLong(num, num3, num, num5, num4, num2, num6, num);
|
||||
}
|
||||
}
|
||||
|
||||
public WhirlpoolDigest()
|
||||
{
|
||||
_rc[0] = 0L;
|
||||
for (int i = 1; i <= 10; i++)
|
||||
{
|
||||
int num = 8 * (i - 1);
|
||||
_rc[i] = (C0[num] & -72057594037927936L) ^ (C1[num + 1] & 0xFF000000000000L) ^ (C2[num + 2] & 0xFF0000000000L) ^ (C3[num + 3] & 0xFF00000000L) ^ (C4[num + 4] & 0xFF000000u) ^ (C5[num + 5] & 0xFF0000) ^ (C6[num + 6] & 0xFF00) ^ (C7[num + 7] & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
private static long packIntoLong(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0)
|
||||
{
|
||||
return ((long)b7 << 56) ^ ((long)b6 << 48) ^ ((long)b5 << 40) ^ ((long)b4 << 32) ^ ((long)b3 << 24) ^ ((long)b2 << 16) ^ ((long)b1 << 8) ^ b0;
|
||||
}
|
||||
|
||||
private static int maskWithReductionPolynomial(int input)
|
||||
{
|
||||
int num = input;
|
||||
if ((long)num >= 256L)
|
||||
{
|
||||
num ^= 0x11D;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public WhirlpoolDigest(WhirlpoolDigest originalDigest)
|
||||
{
|
||||
Reset(originalDigest);
|
||||
}
|
||||
|
||||
public int GetDigestSize()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public int DoFinal(byte[] output, int outOff)
|
||||
{
|
||||
finish();
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
convertLongToByteArray(_hash[i], output, outOff + i * 8);
|
||||
}
|
||||
Reset();
|
||||
return GetDigestSize();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_bufferPos = 0;
|
||||
Array.Clear(_bitCount, 0, _bitCount.Length);
|
||||
Array.Clear(_buffer, 0, _buffer.Length);
|
||||
Array.Clear(_hash, 0, _hash.Length);
|
||||
Array.Clear(_K, 0, _K.Length);
|
||||
Array.Clear(_L, 0, _L.Length);
|
||||
Array.Clear(_block, 0, _block.Length);
|
||||
Array.Clear(_state, 0, _state.Length);
|
||||
}
|
||||
|
||||
private void processFilledBuffer()
|
||||
{
|
||||
for (int i = 0; i < _state.Length; i++)
|
||||
{
|
||||
_block[i] = bytesToLongFromBuffer(_buffer, i * 8);
|
||||
}
|
||||
processBlock();
|
||||
_bufferPos = 0;
|
||||
Array.Clear(_buffer, 0, _buffer.Length);
|
||||
}
|
||||
|
||||
private static long bytesToLongFromBuffer(byte[] buffer, int startPos)
|
||||
{
|
||||
return (long)((((ulong)buffer[startPos] & 0xFFuL) << 56) | (((ulong)buffer[startPos + 1] & 0xFFuL) << 48) | (((ulong)buffer[startPos + 2] & 0xFFuL) << 40) | (((ulong)buffer[startPos + 3] & 0xFFuL) << 32) | (((ulong)buffer[startPos + 4] & 0xFFuL) << 24) | (((ulong)buffer[startPos + 5] & 0xFFuL) << 16) | (((ulong)buffer[startPos + 6] & 0xFFuL) << 8) | ((ulong)buffer[startPos + 7] & 0xFFuL));
|
||||
}
|
||||
|
||||
private static void convertLongToByteArray(long inputLong, byte[] outputArray, int offSet)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
outputArray[offSet + i] = (byte)((inputLong >> 56 - i * 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
private void processBlock()
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
_state[i] = _block[i] ^ (_K[i] = _hash[i]);
|
||||
}
|
||||
for (int j = 1; j <= 10; j++)
|
||||
{
|
||||
long[] l;
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
_L[k] = 0L;
|
||||
long[] array = (l = _L);
|
||||
int num = k;
|
||||
nint num2 = num;
|
||||
array[num] = l[num2] ^ C0[(int)(_K[k & 7] >> 56) & 0xFF];
|
||||
long[] array2 = (l = _L);
|
||||
int num3 = k;
|
||||
num2 = num3;
|
||||
array2[num3] = l[num2] ^ C1[(int)(_K[(k - 1) & 7] >> 48) & 0xFF];
|
||||
long[] array3 = (l = _L);
|
||||
int num4 = k;
|
||||
num2 = num4;
|
||||
array3[num4] = l[num2] ^ C2[(int)(_K[(k - 2) & 7] >> 40) & 0xFF];
|
||||
long[] array4 = (l = _L);
|
||||
int num5 = k;
|
||||
num2 = num5;
|
||||
array4[num5] = l[num2] ^ C3[(int)(_K[(k - 3) & 7] >> 32) & 0xFF];
|
||||
long[] array5 = (l = _L);
|
||||
int num6 = k;
|
||||
num2 = num6;
|
||||
array5[num6] = l[num2] ^ C4[(int)(_K[(k - 4) & 7] >> 24) & 0xFF];
|
||||
long[] array6 = (l = _L);
|
||||
int num7 = k;
|
||||
num2 = num7;
|
||||
array6[num7] = l[num2] ^ C5[(int)(_K[(k - 5) & 7] >> 16) & 0xFF];
|
||||
long[] array7 = (l = _L);
|
||||
int num8 = k;
|
||||
num2 = num8;
|
||||
array7[num8] = l[num2] ^ C6[(int)(_K[(k - 6) & 7] >> 8) & 0xFF];
|
||||
long[] array8 = (l = _L);
|
||||
int num9 = k;
|
||||
num2 = num9;
|
||||
array8[num9] = l[num2] ^ C7[(int)_K[(k - 7) & 7] & 0xFF];
|
||||
}
|
||||
Array.Copy(_L, 0, _K, 0, _K.Length);
|
||||
(l = _K)[0] = l[0] ^ _rc[j];
|
||||
for (int m = 0; m < 8; m++)
|
||||
{
|
||||
_L[m] = _K[m];
|
||||
long[] array9 = (l = _L);
|
||||
int num10 = m;
|
||||
nint num2 = num10;
|
||||
array9[num10] = l[num2] ^ C0[(int)(_state[m & 7] >> 56) & 0xFF];
|
||||
long[] array10 = (l = _L);
|
||||
int num11 = m;
|
||||
num2 = num11;
|
||||
array10[num11] = l[num2] ^ C1[(int)(_state[(m - 1) & 7] >> 48) & 0xFF];
|
||||
long[] array11 = (l = _L);
|
||||
int num12 = m;
|
||||
num2 = num12;
|
||||
array11[num12] = l[num2] ^ C2[(int)(_state[(m - 2) & 7] >> 40) & 0xFF];
|
||||
long[] array12 = (l = _L);
|
||||
int num13 = m;
|
||||
num2 = num13;
|
||||
array12[num13] = l[num2] ^ C3[(int)(_state[(m - 3) & 7] >> 32) & 0xFF];
|
||||
long[] array13 = (l = _L);
|
||||
int num14 = m;
|
||||
num2 = num14;
|
||||
array13[num14] = l[num2] ^ C4[(int)(_state[(m - 4) & 7] >> 24) & 0xFF];
|
||||
long[] array14 = (l = _L);
|
||||
int num15 = m;
|
||||
num2 = num15;
|
||||
array14[num15] = l[num2] ^ C5[(int)(_state[(m - 5) & 7] >> 16) & 0xFF];
|
||||
long[] array15 = (l = _L);
|
||||
int num16 = m;
|
||||
num2 = num16;
|
||||
array15[num16] = l[num2] ^ C6[(int)(_state[(m - 6) & 7] >> 8) & 0xFF];
|
||||
long[] array16 = (l = _L);
|
||||
int num17 = m;
|
||||
num2 = num17;
|
||||
array16[num17] = l[num2] ^ C7[(int)_state[(m - 7) & 7] & 0xFF];
|
||||
}
|
||||
Array.Copy(_L, 0, _state, 0, _state.Length);
|
||||
}
|
||||
for (int n = 0; n < 8; n++)
|
||||
{
|
||||
long[] l;
|
||||
long[] array17 = (l = _hash);
|
||||
int num18 = n;
|
||||
nint num2 = num18;
|
||||
array17[num18] = l[num2] ^ (_state[n] ^ _block[n]);
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(byte input)
|
||||
{
|
||||
_buffer[_bufferPos] = input;
|
||||
_bufferPos++;
|
||||
if (_bufferPos == _buffer.Length)
|
||||
{
|
||||
processFilledBuffer();
|
||||
}
|
||||
increment();
|
||||
}
|
||||
|
||||
private void increment()
|
||||
{
|
||||
int num = 0;
|
||||
for (int num2 = _bitCount.Length - 1; num2 >= 0; num2--)
|
||||
{
|
||||
int num3 = (_bitCount[num2] & 0xFF) + EIGHT[num2] + num;
|
||||
num = num3 >> 8;
|
||||
_bitCount[num2] = (short)(num3 & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
public void BlockUpdate(byte[] input, int inOff, int length)
|
||||
{
|
||||
while (length > 0)
|
||||
{
|
||||
Update(input[inOff]);
|
||||
inOff++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
private void finish()
|
||||
{
|
||||
byte[] array = copyBitLength();
|
||||
byte[] buffer;
|
||||
byte[] array2 = (buffer = _buffer);
|
||||
int num = _bufferPos++;
|
||||
nint num2 = num;
|
||||
array2[num] = (byte)(buffer[num2] | 0x80);
|
||||
if (_bufferPos == _buffer.Length)
|
||||
{
|
||||
processFilledBuffer();
|
||||
}
|
||||
if (_bufferPos > 32)
|
||||
{
|
||||
while (_bufferPos != 0)
|
||||
{
|
||||
Update(0);
|
||||
}
|
||||
}
|
||||
while (_bufferPos <= 32)
|
||||
{
|
||||
Update(0);
|
||||
}
|
||||
Array.Copy(array, 0, _buffer, 32, array.Length);
|
||||
processFilledBuffer();
|
||||
}
|
||||
|
||||
private byte[] copyBitLength()
|
||||
{
|
||||
byte[] array = new byte[32];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] = (byte)(_bitCount[i] & 0xFF);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public int GetByteLength()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public IMemoable Copy()
|
||||
{
|
||||
return new WhirlpoolDigest(this);
|
||||
}
|
||||
|
||||
public void Reset(IMemoable other)
|
||||
{
|
||||
WhirlpoolDigest whirlpoolDigest = (WhirlpoolDigest)other;
|
||||
Array.Copy(whirlpoolDigest._rc, 0, _rc, 0, _rc.Length);
|
||||
Array.Copy(whirlpoolDigest._buffer, 0, _buffer, 0, _buffer.Length);
|
||||
_bufferPos = whirlpoolDigest._bufferPos;
|
||||
Array.Copy(whirlpoolDigest._bitCount, 0, _bitCount, 0, _bitCount.Length);
|
||||
Array.Copy(whirlpoolDigest._hash, 0, _hash, 0, _hash.Length);
|
||||
Array.Copy(whirlpoolDigest._K, 0, _K, 0, _K.Length);
|
||||
Array.Copy(whirlpoolDigest._L, 0, _L, 0, _L.Length);
|
||||
Array.Copy(whirlpoolDigest._block, 0, _block, 0, _block.Length);
|
||||
Array.Copy(whirlpoolDigest._state, 0, _state, 0, _state.Length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,736 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.GM;
|
||||
using Org.BouncyCastle.Asn1.Sec;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Math.EC;
|
||||
using Org.BouncyCastle.Math.EC.Custom.Djb;
|
||||
using Org.BouncyCastle.Math.EC.Custom.GM;
|
||||
using Org.BouncyCastle.Math.EC.Custom.Sec;
|
||||
using Org.BouncyCastle.Math.EC.Endo;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.EC;
|
||||
|
||||
public sealed class CustomNamedCurves
|
||||
{
|
||||
internal class Curve25519Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new Curve25519Holder();
|
||||
|
||||
private Curve25519Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
ECCurve eCCurve = ConfigureCurve(new Curve25519());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("042AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP128R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP128R1Holder();
|
||||
|
||||
private SecP128R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("000E0D4D696E6768756151750CC03A4473D03679");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecP128R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP160K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP160K1Holder();
|
||||
|
||||
private SecP160K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
GlvTypeBParameters p = new GlvTypeBParameters(new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16), new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16), new BigInteger[2]
|
||||
{
|
||||
new BigInteger("9162fbe73984472a0a9e", 16),
|
||||
new BigInteger("-96341f1138933bc2f505", 16)
|
||||
}, new BigInteger[2]
|
||||
{
|
||||
new BigInteger("127971af8721782ecffa3", 16),
|
||||
new BigInteger("9162fbe73984472a0a9e", 16)
|
||||
}, new BigInteger("9162fbe73984472a0a9d0590", 16), new BigInteger("96341f1138933bc2f503fd44", 16), 176);
|
||||
ECCurve eCCurve = ConfigureCurveGlv(new SecP160K1Curve(), p);
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP160R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP160R1Holder();
|
||||
|
||||
private SecP160R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("1053CDE42C14D696E67687561517533BF3F83345");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecP160R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP160R2Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP160R2Holder();
|
||||
|
||||
private SecP160R2Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("B99B99B099B323E02709A4D696E6768756151751");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecP160R2Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP192K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP192K1Holder();
|
||||
|
||||
private SecP192K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
GlvTypeBParameters p = new GlvTypeBParameters(new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16), new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16), new BigInteger[2]
|
||||
{
|
||||
new BigInteger("71169be7330b3038edb025f1", 16),
|
||||
new BigInteger("-b3fb3400dec5c4adceb8655c", 16)
|
||||
}, new BigInteger[2]
|
||||
{
|
||||
new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
|
||||
new BigInteger("71169be7330b3038edb025f1", 16)
|
||||
}, new BigInteger("71169be7330b3038edb025f1d0f9", 16), new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), 208);
|
||||
ECCurve eCCurve = ConfigureCurveGlv(new SecP192K1Curve(), p);
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP192R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP192R1Holder();
|
||||
|
||||
private SecP192R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("3045AE6FC8422F64ED579528D38120EAE12196D5");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecP192R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP224K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP224K1Holder();
|
||||
|
||||
private SecP224K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
GlvTypeBParameters p = new GlvTypeBParameters(new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16), new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16), new BigInteger[2]
|
||||
{
|
||||
new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
|
||||
new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16)
|
||||
}, new BigInteger[2]
|
||||
{
|
||||
new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
|
||||
new BigInteger("6b8cf07d4ca75c88957d9d670591", 16)
|
||||
}, new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), 240);
|
||||
ECCurve eCCurve = ConfigureCurveGlv(new SecP224K1Curve(), p);
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP224R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP224R1Holder();
|
||||
|
||||
private SecP224R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecP224R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP256K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP256K1Holder();
|
||||
|
||||
private SecP256K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
GlvTypeBParameters p = new GlvTypeBParameters(new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16), new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16), new BigInteger[2]
|
||||
{
|
||||
new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
|
||||
new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16)
|
||||
}, new BigInteger[2]
|
||||
{
|
||||
new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
|
||||
new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16)
|
||||
}, new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), 272);
|
||||
ECCurve eCCurve = ConfigureCurveGlv(new SecP256K1Curve(), p);
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP256R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP256R1Holder();
|
||||
|
||||
private SecP256R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("C49D360886E704936A6678E1139D26B7819F7E90");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecP256R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP384R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP384R1Holder();
|
||||
|
||||
private SecP384R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("A335926AA319A27A1D00896A6773A4827ACDAC73");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecP384R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecP521R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecP521R1Holder();
|
||||
|
||||
private SecP521R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("D09E8800291CB85396CC6717393284AAA0DA64BA");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecP521R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT113R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT113R1Holder();
|
||||
|
||||
private SecT113R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("10E723AB14D696E6768756151756FEBF8FCB49A9");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT113R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT113R2Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT113R2Holder();
|
||||
|
||||
private SecT113R2Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("10C0FB15760860DEF1EEF4D696E676875615175D");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT113R2Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT131R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT131R1Holder();
|
||||
|
||||
private SecT131R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("4D696E676875615175985BD3ADBADA21B43A97E2");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT131R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT131R2Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT131R2Holder();
|
||||
|
||||
private SecT131R2Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("985BD3ADBAD4D696E676875615175A21B43A97E3");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT131R2Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT163K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT163K1Holder();
|
||||
|
||||
private SecT163K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT163K1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT163R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT163R1Holder();
|
||||
|
||||
private SecT163R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("24B7B137C8A14D696E6768756151756FD0DA2E5C");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT163R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT163R2Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT163R2Holder();
|
||||
|
||||
private SecT163R2Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("85E25BFE5C86226CDB12016F7553F9D0E693A268");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT163R2Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT193R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT193R1Holder();
|
||||
|
||||
private SecT193R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("103FAEC74D696E676875615175777FC5B191EF30");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT193R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT193R2Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT193R2Holder();
|
||||
|
||||
private SecT193R2Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("10B7B4D696E676875615175137C8A16FD0DA2211");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT193R2Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT233K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT233K1Holder();
|
||||
|
||||
private SecT233K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT233K1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT233R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT233R1Holder();
|
||||
|
||||
private SecT233R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT233R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT239K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT239K1Holder();
|
||||
|
||||
private SecT239K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT239K1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT283K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT283K1Holder();
|
||||
|
||||
private SecT283K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT283K1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("040503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC245849283601CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT283R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT283R1Holder();
|
||||
|
||||
private SecT283R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT283R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0405F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B1205303676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT409K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT409K1Holder();
|
||||
|
||||
private SecT409K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT409K1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("040060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE902374601E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT409R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT409R1Holder();
|
||||
|
||||
private SecT409R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("4099B5A457F9D69F79213D094C4BCD4D4262210B");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT409R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A70061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT571K1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT571K1Holder();
|
||||
|
||||
private SecT571K1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT571K1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("04026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C89720349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SecT571R1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SecT571R1Holder();
|
||||
|
||||
private SecT571R1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = Hex.Decode("2AA058F73A0E33AB486B0F610410C53A7F132310");
|
||||
ECCurve eCCurve = ConfigureCurve(new SecT571R1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("040303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SM2P256V1Holder : X9ECParametersHolder
|
||||
{
|
||||
internal static readonly X9ECParametersHolder Instance = new SM2P256V1Holder();
|
||||
|
||||
private SM2P256V1Holder()
|
||||
{
|
||||
}
|
||||
|
||||
protected override X9ECParameters CreateParameters()
|
||||
{
|
||||
byte[] seed = null;
|
||||
ECCurve eCCurve = ConfigureCurve(new SM2P256V1Curve());
|
||||
X9ECPoint g = new X9ECPoint(eCCurve, Hex.Decode("0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"));
|
||||
return new X9ECParameters(eCCurve, g, eCCurve.Order, eCCurve.Cofactor, seed);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly IDictionary nameToCurve;
|
||||
|
||||
private static readonly IDictionary nameToOid;
|
||||
|
||||
private static readonly IDictionary oidToCurve;
|
||||
|
||||
private static readonly IDictionary oidToName;
|
||||
|
||||
private static readonly IList names;
|
||||
|
||||
public static IEnumerable Names => new EnumerableProxy(names);
|
||||
|
||||
private CustomNamedCurves()
|
||||
{
|
||||
}
|
||||
|
||||
private static BigInteger FromHex(string hex)
|
||||
{
|
||||
return new BigInteger(1, Hex.Decode(hex));
|
||||
}
|
||||
|
||||
private static ECCurve ConfigureCurve(ECCurve curve)
|
||||
{
|
||||
return curve;
|
||||
}
|
||||
|
||||
private static ECCurve ConfigureCurveGlv(ECCurve c, GlvTypeBParameters p)
|
||||
{
|
||||
return c.Configure().SetEndomorphism(new GlvTypeBEndomorphism(c, p)).Create();
|
||||
}
|
||||
|
||||
private static void DefineCurve(string name, X9ECParametersHolder holder)
|
||||
{
|
||||
names.Add(name);
|
||||
name = Platform.ToUpperInvariant(name);
|
||||
nameToCurve.Add(name, holder);
|
||||
}
|
||||
|
||||
private static void DefineCurveWithOid(string name, DerObjectIdentifier oid, X9ECParametersHolder holder)
|
||||
{
|
||||
names.Add(name);
|
||||
oidToName.Add(oid, name);
|
||||
oidToCurve.Add(oid, holder);
|
||||
name = Platform.ToUpperInvariant(name);
|
||||
nameToOid.Add(name, oid);
|
||||
nameToCurve.Add(name, holder);
|
||||
}
|
||||
|
||||
private static void DefineCurveAlias(string name, DerObjectIdentifier oid)
|
||||
{
|
||||
object obj = oidToCurve[oid];
|
||||
if (obj == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
name = Platform.ToUpperInvariant(name);
|
||||
nameToOid.Add(name, oid);
|
||||
nameToCurve.Add(name, obj);
|
||||
}
|
||||
|
||||
static CustomNamedCurves()
|
||||
{
|
||||
nameToCurve = Platform.CreateHashtable();
|
||||
nameToOid = Platform.CreateHashtable();
|
||||
oidToCurve = Platform.CreateHashtable();
|
||||
oidToName = Platform.CreateHashtable();
|
||||
names = Platform.CreateArrayList();
|
||||
DefineCurve("curve25519", Curve25519Holder.Instance);
|
||||
DefineCurveWithOid("secp128r1", SecObjectIdentifiers.SecP128r1, SecP128R1Holder.Instance);
|
||||
DefineCurveWithOid("secp160k1", SecObjectIdentifiers.SecP160k1, SecP160K1Holder.Instance);
|
||||
DefineCurveWithOid("secp160r1", SecObjectIdentifiers.SecP160r1, SecP160R1Holder.Instance);
|
||||
DefineCurveWithOid("secp160r2", SecObjectIdentifiers.SecP160r2, SecP160R2Holder.Instance);
|
||||
DefineCurveWithOid("secp192k1", SecObjectIdentifiers.SecP192k1, SecP192K1Holder.Instance);
|
||||
DefineCurveWithOid("secp192r1", SecObjectIdentifiers.SecP192r1, SecP192R1Holder.Instance);
|
||||
DefineCurveWithOid("secp224k1", SecObjectIdentifiers.SecP224k1, SecP224K1Holder.Instance);
|
||||
DefineCurveWithOid("secp224r1", SecObjectIdentifiers.SecP224r1, SecP224R1Holder.Instance);
|
||||
DefineCurveWithOid("secp256k1", SecObjectIdentifiers.SecP256k1, SecP256K1Holder.Instance);
|
||||
DefineCurveWithOid("secp256r1", SecObjectIdentifiers.SecP256r1, SecP256R1Holder.Instance);
|
||||
DefineCurveWithOid("secp384r1", SecObjectIdentifiers.SecP384r1, SecP384R1Holder.Instance);
|
||||
DefineCurveWithOid("secp521r1", SecObjectIdentifiers.SecP521r1, SecP521R1Holder.Instance);
|
||||
DefineCurveWithOid("sect113r1", SecObjectIdentifiers.SecT113r1, SecT113R1Holder.Instance);
|
||||
DefineCurveWithOid("sect113r2", SecObjectIdentifiers.SecT113r2, SecT113R2Holder.Instance);
|
||||
DefineCurveWithOid("sect131r1", SecObjectIdentifiers.SecT131r1, SecT131R1Holder.Instance);
|
||||
DefineCurveWithOid("sect131r2", SecObjectIdentifiers.SecT131r2, SecT131R2Holder.Instance);
|
||||
DefineCurveWithOid("sect163k1", SecObjectIdentifiers.SecT163k1, SecT163K1Holder.Instance);
|
||||
DefineCurveWithOid("sect163r1", SecObjectIdentifiers.SecT163r1, SecT163R1Holder.Instance);
|
||||
DefineCurveWithOid("sect163r2", SecObjectIdentifiers.SecT163r2, SecT163R2Holder.Instance);
|
||||
DefineCurveWithOid("sect193r1", SecObjectIdentifiers.SecT193r1, SecT193R1Holder.Instance);
|
||||
DefineCurveWithOid("sect193r2", SecObjectIdentifiers.SecT193r2, SecT193R2Holder.Instance);
|
||||
DefineCurveWithOid("sect233k1", SecObjectIdentifiers.SecT233k1, SecT233K1Holder.Instance);
|
||||
DefineCurveWithOid("sect233r1", SecObjectIdentifiers.SecT233r1, SecT233R1Holder.Instance);
|
||||
DefineCurveWithOid("sect239k1", SecObjectIdentifiers.SecT239k1, SecT239K1Holder.Instance);
|
||||
DefineCurveWithOid("sect283k1", SecObjectIdentifiers.SecT283k1, SecT283K1Holder.Instance);
|
||||
DefineCurveWithOid("sect283r1", SecObjectIdentifiers.SecT283r1, SecT283R1Holder.Instance);
|
||||
DefineCurveWithOid("sect409k1", SecObjectIdentifiers.SecT409k1, SecT409K1Holder.Instance);
|
||||
DefineCurveWithOid("sect409r1", SecObjectIdentifiers.SecT409r1, SecT409R1Holder.Instance);
|
||||
DefineCurveWithOid("sect571k1", SecObjectIdentifiers.SecT571k1, SecT571K1Holder.Instance);
|
||||
DefineCurveWithOid("sect571r1", SecObjectIdentifiers.SecT571r1, SecT571R1Holder.Instance);
|
||||
DefineCurveWithOid("sm2p256v1", GMObjectIdentifiers.sm2p256v1, SM2P256V1Holder.Instance);
|
||||
DefineCurveAlias("B-163", SecObjectIdentifiers.SecT163r2);
|
||||
DefineCurveAlias("B-233", SecObjectIdentifiers.SecT233r1);
|
||||
DefineCurveAlias("B-283", SecObjectIdentifiers.SecT283r1);
|
||||
DefineCurveAlias("B-409", SecObjectIdentifiers.SecT409r1);
|
||||
DefineCurveAlias("B-571", SecObjectIdentifiers.SecT571r1);
|
||||
DefineCurveAlias("K-163", SecObjectIdentifiers.SecT163k1);
|
||||
DefineCurveAlias("K-233", SecObjectIdentifiers.SecT233k1);
|
||||
DefineCurveAlias("K-283", SecObjectIdentifiers.SecT283k1);
|
||||
DefineCurveAlias("K-409", SecObjectIdentifiers.SecT409k1);
|
||||
DefineCurveAlias("K-571", SecObjectIdentifiers.SecT571k1);
|
||||
DefineCurveAlias("P-192", SecObjectIdentifiers.SecP192r1);
|
||||
DefineCurveAlias("P-224", SecObjectIdentifiers.SecP224r1);
|
||||
DefineCurveAlias("P-256", SecObjectIdentifiers.SecP256r1);
|
||||
DefineCurveAlias("P-384", SecObjectIdentifiers.SecP384r1);
|
||||
DefineCurveAlias("P-521", SecObjectIdentifiers.SecP521r1);
|
||||
}
|
||||
|
||||
public static X9ECParameters GetByName(string name)
|
||||
{
|
||||
return ((X9ECParametersHolder)nameToCurve[Platform.ToUpperInvariant(name)])?.Parameters;
|
||||
}
|
||||
|
||||
public static X9ECParameters GetByOid(DerObjectIdentifier oid)
|
||||
{
|
||||
return ((X9ECParametersHolder)oidToCurve[oid])?.Parameters;
|
||||
}
|
||||
|
||||
public static DerObjectIdentifier GetOid(string name)
|
||||
{
|
||||
return (DerObjectIdentifier)nameToOid[Platform.ToUpperInvariant(name)];
|
||||
}
|
||||
|
||||
public static string GetName(DerObjectIdentifier oid)
|
||||
{
|
||||
return (string)oidToName[oid];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Encodings;
|
||||
|
||||
public class ISO9796d1Encoding : IAsymmetricBlockCipher
|
||||
{
|
||||
private static readonly BigInteger Sixteen = BigInteger.ValueOf(16L);
|
||||
|
||||
private static readonly BigInteger Six = BigInteger.ValueOf(6L);
|
||||
|
||||
private static readonly byte[] shadows = new byte[16]
|
||||
{
|
||||
14, 3, 5, 8, 9, 4, 2, 15, 0, 13,
|
||||
11, 6, 7, 10, 12, 1
|
||||
};
|
||||
|
||||
private static readonly byte[] inverse = new byte[16]
|
||||
{
|
||||
8, 15, 6, 1, 5, 2, 11, 12, 3, 4,
|
||||
13, 10, 14, 9, 0, 7
|
||||
};
|
||||
|
||||
private readonly IAsymmetricBlockCipher engine;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
private int bitSize;
|
||||
|
||||
private int padBits = 0;
|
||||
|
||||
private BigInteger modulus;
|
||||
|
||||
public string AlgorithmName => engine.AlgorithmName + "/ISO9796-1Padding";
|
||||
|
||||
public ISO9796d1Encoding(IAsymmetricBlockCipher cipher)
|
||||
{
|
||||
engine = cipher;
|
||||
}
|
||||
|
||||
public IAsymmetricBlockCipher GetUnderlyingCipher()
|
||||
{
|
||||
return engine;
|
||||
}
|
||||
|
||||
public void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
RsaKeyParameters rsaKeyParameters;
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
|
||||
rsaKeyParameters = (RsaKeyParameters)parametersWithRandom.Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
rsaKeyParameters = (RsaKeyParameters)parameters;
|
||||
}
|
||||
engine.Init(forEncryption, parameters);
|
||||
modulus = rsaKeyParameters.Modulus;
|
||||
bitSize = modulus.BitLength;
|
||||
this.forEncryption = forEncryption;
|
||||
}
|
||||
|
||||
public int GetInputBlockSize()
|
||||
{
|
||||
int inputBlockSize = engine.GetInputBlockSize();
|
||||
if (forEncryption)
|
||||
{
|
||||
return (inputBlockSize + 1) / 2;
|
||||
}
|
||||
return inputBlockSize;
|
||||
}
|
||||
|
||||
public int GetOutputBlockSize()
|
||||
{
|
||||
int outputBlockSize = engine.GetOutputBlockSize();
|
||||
if (forEncryption)
|
||||
{
|
||||
return outputBlockSize;
|
||||
}
|
||||
return (outputBlockSize + 1) / 2;
|
||||
}
|
||||
|
||||
public void SetPadBits(int padBits)
|
||||
{
|
||||
if (padBits > 7)
|
||||
{
|
||||
throw new ArgumentException("padBits > 7");
|
||||
}
|
||||
this.padBits = padBits;
|
||||
}
|
||||
|
||||
public int GetPadBits()
|
||||
{
|
||||
return padBits;
|
||||
}
|
||||
|
||||
public byte[] ProcessBlock(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
return EncodeBlock(input, inOff, length);
|
||||
}
|
||||
return DecodeBlock(input, inOff, length);
|
||||
}
|
||||
|
||||
private byte[] EncodeBlock(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
byte[] array = new byte[(bitSize + 7) / 8];
|
||||
int num = padBits + 1;
|
||||
int num2 = (bitSize + 13) / 16;
|
||||
for (int i = 0; i < num2; i += inLen)
|
||||
{
|
||||
if (i > num2 - inLen)
|
||||
{
|
||||
Array.Copy(input, inOff + inLen - (num2 - i), array, array.Length - num2, num2 - i);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(input, inOff, array, array.Length - (i + inLen), inLen);
|
||||
}
|
||||
}
|
||||
for (int j = array.Length - 2 * num2; j != array.Length; j += 2)
|
||||
{
|
||||
byte b = array[array.Length - num2 + j / 2];
|
||||
array[j] = (byte)((shadows[(b & 0xFF) >>> 4] << 4) | shadows[b & 0xF]);
|
||||
array[j + 1] = b;
|
||||
}
|
||||
byte[] array3;
|
||||
byte[] array2 = (array3 = array);
|
||||
int num3 = array.Length - 2 * inLen;
|
||||
nint num4 = num3;
|
||||
array2[num3] = (byte)(array3[num4] ^ (byte)num);
|
||||
array[^1] = (byte)((array[^1] << 4) | 6);
|
||||
int num5 = 8 - (bitSize - 1) % 8;
|
||||
int num6 = 0;
|
||||
if (num5 != 8)
|
||||
{
|
||||
(array3 = array)[0] = (byte)(array3[0] & (byte)(255 >> num5));
|
||||
(array3 = array)[0] = (byte)(array3[0] | (byte)(128 >> num5));
|
||||
}
|
||||
else
|
||||
{
|
||||
array[0] = 0;
|
||||
(array3 = array)[1] = (byte)(array3[1] | 0x80);
|
||||
num6 = 1;
|
||||
}
|
||||
return engine.ProcessBlock(array, num6, array.Length - num6);
|
||||
}
|
||||
|
||||
private byte[] DecodeBlock(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
byte[] bytes = engine.ProcessBlock(input, inOff, inLen);
|
||||
int num = 1;
|
||||
int num2 = (bitSize + 13) / 16;
|
||||
BigInteger bigInteger = new BigInteger(1, bytes);
|
||||
BigInteger bigInteger2;
|
||||
if (bigInteger.Mod(Sixteen).Equals(Six))
|
||||
{
|
||||
bigInteger2 = bigInteger;
|
||||
}
|
||||
else
|
||||
{
|
||||
bigInteger2 = modulus.Subtract(bigInteger);
|
||||
if (!bigInteger2.Mod(Sixteen).Equals(Six))
|
||||
{
|
||||
throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16");
|
||||
}
|
||||
}
|
||||
bytes = bigInteger2.ToByteArrayUnsigned();
|
||||
if ((bytes[^1] & 0xF) != 6)
|
||||
{
|
||||
throw new InvalidCipherTextException("invalid forcing byte in block");
|
||||
}
|
||||
bytes[^1] = (byte)(((ushort)(bytes[^1] & 0xFF) >> 4) | (inverse[(bytes[^2] & 0xFF) >> 4] << 4));
|
||||
bytes[0] = (byte)((shadows[(bytes[1] & 0xFF) >>> 4] << 4) | shadows[bytes[1] & 0xF]);
|
||||
bool flag = false;
|
||||
int num3 = 0;
|
||||
for (int num4 = bytes.Length - 1; num4 >= bytes.Length - 2 * num2; num4 -= 2)
|
||||
{
|
||||
int num5 = (shadows[(bytes[num4] & 0xFF) >>> 4] << 4) | shadows[bytes[num4] & 0xF];
|
||||
if (((bytes[num4 - 1] ^ num5) & 0xFF) != 0)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
throw new InvalidCipherTextException("invalid tsums in block");
|
||||
}
|
||||
flag = true;
|
||||
num = (bytes[num4 - 1] ^ num5) & 0xFF;
|
||||
num3 = num4 - 1;
|
||||
}
|
||||
}
|
||||
bytes[num3] = 0;
|
||||
byte[] array = new byte[(bytes.Length - num3) / 2];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] = bytes[2 * i + num3 + 1];
|
||||
}
|
||||
padBits = num - 1;
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Digests;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Encodings;
|
||||
|
||||
public class OaepEncoding : IAsymmetricBlockCipher
|
||||
{
|
||||
private byte[] defHash;
|
||||
|
||||
private IDigest mgf1Hash;
|
||||
|
||||
private IAsymmetricBlockCipher engine;
|
||||
|
||||
private SecureRandom random;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
public string AlgorithmName => engine.AlgorithmName + "/OAEPPadding";
|
||||
|
||||
public OaepEncoding(IAsymmetricBlockCipher cipher)
|
||||
: this(cipher, new Sha1Digest(), null)
|
||||
{
|
||||
}
|
||||
|
||||
public OaepEncoding(IAsymmetricBlockCipher cipher, IDigest hash)
|
||||
: this(cipher, hash, null)
|
||||
{
|
||||
}
|
||||
|
||||
public OaepEncoding(IAsymmetricBlockCipher cipher, IDigest hash, byte[] encodingParams)
|
||||
: this(cipher, hash, hash, encodingParams)
|
||||
{
|
||||
}
|
||||
|
||||
public OaepEncoding(IAsymmetricBlockCipher cipher, IDigest hash, IDigest mgf1Hash, byte[] encodingParams)
|
||||
{
|
||||
engine = cipher;
|
||||
this.mgf1Hash = mgf1Hash;
|
||||
defHash = new byte[hash.GetDigestSize()];
|
||||
hash.Reset();
|
||||
if (encodingParams != null)
|
||||
{
|
||||
hash.BlockUpdate(encodingParams, 0, encodingParams.Length);
|
||||
}
|
||||
hash.DoFinal(defHash, 0);
|
||||
}
|
||||
|
||||
public IAsymmetricBlockCipher GetUnderlyingCipher()
|
||||
{
|
||||
return engine;
|
||||
}
|
||||
|
||||
public void Init(bool forEncryption, ICipherParameters param)
|
||||
{
|
||||
if (param is ParametersWithRandom)
|
||||
{
|
||||
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)param;
|
||||
random = parametersWithRandom.Random;
|
||||
}
|
||||
else
|
||||
{
|
||||
random = new SecureRandom();
|
||||
}
|
||||
engine.Init(forEncryption, param);
|
||||
this.forEncryption = forEncryption;
|
||||
}
|
||||
|
||||
public int GetInputBlockSize()
|
||||
{
|
||||
int inputBlockSize = engine.GetInputBlockSize();
|
||||
if (forEncryption)
|
||||
{
|
||||
return inputBlockSize - 1 - 2 * defHash.Length;
|
||||
}
|
||||
return inputBlockSize;
|
||||
}
|
||||
|
||||
public int GetOutputBlockSize()
|
||||
{
|
||||
int outputBlockSize = engine.GetOutputBlockSize();
|
||||
if (forEncryption)
|
||||
{
|
||||
return outputBlockSize;
|
||||
}
|
||||
return outputBlockSize - 1 - 2 * defHash.Length;
|
||||
}
|
||||
|
||||
public byte[] ProcessBlock(byte[] inBytes, int inOff, int inLen)
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
return EncodeBlock(inBytes, inOff, inLen);
|
||||
}
|
||||
return DecodeBlock(inBytes, inOff, inLen);
|
||||
}
|
||||
|
||||
private byte[] EncodeBlock(byte[] inBytes, int inOff, int inLen)
|
||||
{
|
||||
Check.DataLength(inLen > GetInputBlockSize(), "input data too long");
|
||||
byte[] array = new byte[GetInputBlockSize() + 1 + 2 * defHash.Length];
|
||||
Array.Copy(inBytes, inOff, array, array.Length - inLen, inLen);
|
||||
array[array.Length - inLen - 1] = 1;
|
||||
Array.Copy(defHash, 0, array, defHash.Length, defHash.Length);
|
||||
byte[] nextBytes = SecureRandom.GetNextBytes(random, defHash.Length);
|
||||
byte[] array2 = maskGeneratorFunction1(nextBytes, 0, nextBytes.Length, array.Length - defHash.Length);
|
||||
for (int i = defHash.Length; i != array.Length; i++)
|
||||
{
|
||||
byte[] array4;
|
||||
byte[] array3 = (array4 = array);
|
||||
int num = i;
|
||||
nint num2 = num;
|
||||
array3[num] = (byte)(array4[num2] ^ array2[i - defHash.Length]);
|
||||
}
|
||||
Array.Copy(nextBytes, 0, array, 0, defHash.Length);
|
||||
array2 = maskGeneratorFunction1(array, defHash.Length, array.Length - defHash.Length, defHash.Length);
|
||||
for (int j = 0; j != defHash.Length; j++)
|
||||
{
|
||||
byte[] array4;
|
||||
byte[] array5 = (array4 = array);
|
||||
int num3 = j;
|
||||
nint num2 = num3;
|
||||
array5[num3] = (byte)(array4[num2] ^ array2[j]);
|
||||
}
|
||||
return engine.ProcessBlock(array, 0, array.Length);
|
||||
}
|
||||
|
||||
private byte[] DecodeBlock(byte[] inBytes, int inOff, int inLen)
|
||||
{
|
||||
byte[] array = engine.ProcessBlock(inBytes, inOff, inLen);
|
||||
byte[] array2 = new byte[engine.GetOutputBlockSize()];
|
||||
bool flag = array2.Length < 2 * defHash.Length + 1;
|
||||
if (array.Length <= array2.Length)
|
||||
{
|
||||
Array.Copy(array, 0, array2, array2.Length - array.Length, array.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(array, 0, array2, 0, array2.Length);
|
||||
flag = true;
|
||||
}
|
||||
byte[] array3 = maskGeneratorFunction1(array2, defHash.Length, array2.Length - defHash.Length, defHash.Length);
|
||||
for (int i = 0; i != defHash.Length; i++)
|
||||
{
|
||||
byte[] array5;
|
||||
byte[] array4 = (array5 = array2);
|
||||
int num = i;
|
||||
nint num2 = num;
|
||||
array4[num] = (byte)(array5[num2] ^ array3[i]);
|
||||
}
|
||||
array3 = maskGeneratorFunction1(array2, 0, defHash.Length, array2.Length - defHash.Length);
|
||||
for (int j = defHash.Length; j != array2.Length; j++)
|
||||
{
|
||||
byte[] array5;
|
||||
byte[] array6 = (array5 = array2);
|
||||
int num3 = j;
|
||||
nint num2 = num3;
|
||||
array6[num3] = (byte)(array5[num2] ^ array3[j - defHash.Length]);
|
||||
}
|
||||
bool flag2 = false;
|
||||
for (int k = 0; k != defHash.Length; k++)
|
||||
{
|
||||
if (defHash[k] != array2[defHash.Length + k])
|
||||
{
|
||||
flag2 = true;
|
||||
}
|
||||
}
|
||||
int num4 = array2.Length;
|
||||
for (int l = 2 * defHash.Length; l != array2.Length; l++)
|
||||
{
|
||||
if ((array2[l] != 0) & (num4 == array2.Length))
|
||||
{
|
||||
num4 = l;
|
||||
}
|
||||
}
|
||||
bool flag3 = (num4 > array2.Length - 1) | (array2[num4] != 1);
|
||||
num4++;
|
||||
if (flag2 || flag || flag3)
|
||||
{
|
||||
Arrays.Fill(array2, 0);
|
||||
throw new InvalidCipherTextException("data wrong");
|
||||
}
|
||||
byte[] array7 = new byte[array2.Length - num4];
|
||||
Array.Copy(array2, num4, array7, 0, array7.Length);
|
||||
return array7;
|
||||
}
|
||||
|
||||
private void ItoOSP(int i, byte[] sp)
|
||||
{
|
||||
sp[0] = (byte)((uint)i >> 24);
|
||||
sp[1] = (byte)((uint)i >> 16);
|
||||
sp[2] = (byte)((uint)i >> 8);
|
||||
sp[3] = (byte)i;
|
||||
}
|
||||
|
||||
private byte[] maskGeneratorFunction1(byte[] Z, int zOff, int zLen, int length)
|
||||
{
|
||||
byte[] array = new byte[length];
|
||||
byte[] array2 = new byte[mgf1Hash.GetDigestSize()];
|
||||
byte[] array3 = new byte[4];
|
||||
int i = 0;
|
||||
mgf1Hash.Reset();
|
||||
for (; i < length / array2.Length; i++)
|
||||
{
|
||||
ItoOSP(i, array3);
|
||||
mgf1Hash.BlockUpdate(Z, zOff, zLen);
|
||||
mgf1Hash.BlockUpdate(array3, 0, array3.Length);
|
||||
mgf1Hash.DoFinal(array2, 0);
|
||||
Array.Copy(array2, 0, array, i * array2.Length, array2.Length);
|
||||
}
|
||||
if (i * array2.Length < length)
|
||||
{
|
||||
ItoOSP(i, array3);
|
||||
mgf1Hash.BlockUpdate(Z, zOff, zLen);
|
||||
mgf1Hash.BlockUpdate(array3, 0, array3.Length);
|
||||
mgf1Hash.DoFinal(array2, 0);
|
||||
Array.Copy(array2, 0, array, i * array2.Length, array.Length - i * array2.Length);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Encodings;
|
||||
|
||||
public class Pkcs1Encoding : IAsymmetricBlockCipher
|
||||
{
|
||||
public const string StrictLengthEnabledProperty = "Org.BouncyCastle.Pkcs1.Strict";
|
||||
|
||||
private const int HeaderLength = 10;
|
||||
|
||||
private static readonly bool[] strictLengthEnabled;
|
||||
|
||||
private SecureRandom random;
|
||||
|
||||
private IAsymmetricBlockCipher engine;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
private bool forPrivateKey;
|
||||
|
||||
private bool useStrictLength;
|
||||
|
||||
private int pLen = -1;
|
||||
|
||||
private byte[] fallback = null;
|
||||
|
||||
private byte[] blockBuffer = null;
|
||||
|
||||
public static bool StrictLengthEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return strictLengthEnabled[0];
|
||||
}
|
||||
set
|
||||
{
|
||||
strictLengthEnabled[0] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string AlgorithmName => engine.AlgorithmName + "/PKCS1Padding";
|
||||
|
||||
static Pkcs1Encoding()
|
||||
{
|
||||
string environmentVariable = Platform.GetEnvironmentVariable("Org.BouncyCastle.Pkcs1.Strict");
|
||||
strictLengthEnabled = new bool[1] { environmentVariable?.Equals("true") ?? true };
|
||||
}
|
||||
|
||||
public Pkcs1Encoding(IAsymmetricBlockCipher cipher)
|
||||
{
|
||||
engine = cipher;
|
||||
useStrictLength = StrictLengthEnabled;
|
||||
}
|
||||
|
||||
public Pkcs1Encoding(IAsymmetricBlockCipher cipher, int pLen)
|
||||
{
|
||||
engine = cipher;
|
||||
useStrictLength = StrictLengthEnabled;
|
||||
this.pLen = pLen;
|
||||
}
|
||||
|
||||
public Pkcs1Encoding(IAsymmetricBlockCipher cipher, byte[] fallback)
|
||||
{
|
||||
engine = cipher;
|
||||
useStrictLength = StrictLengthEnabled;
|
||||
this.fallback = fallback;
|
||||
pLen = fallback.Length;
|
||||
}
|
||||
|
||||
public IAsymmetricBlockCipher GetUnderlyingCipher()
|
||||
{
|
||||
return engine;
|
||||
}
|
||||
|
||||
public void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
AsymmetricKeyParameter asymmetricKeyParameter;
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
|
||||
random = parametersWithRandom.Random;
|
||||
asymmetricKeyParameter = (AsymmetricKeyParameter)parametersWithRandom.Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
random = new SecureRandom();
|
||||
asymmetricKeyParameter = (AsymmetricKeyParameter)parameters;
|
||||
}
|
||||
engine.Init(forEncryption, parameters);
|
||||
forPrivateKey = asymmetricKeyParameter.IsPrivate;
|
||||
this.forEncryption = forEncryption;
|
||||
blockBuffer = new byte[engine.GetOutputBlockSize()];
|
||||
if (pLen > 0 && fallback == null && random == null)
|
||||
{
|
||||
throw new ArgumentException("encoder requires random");
|
||||
}
|
||||
}
|
||||
|
||||
public int GetInputBlockSize()
|
||||
{
|
||||
int inputBlockSize = engine.GetInputBlockSize();
|
||||
if (!forEncryption)
|
||||
{
|
||||
return inputBlockSize;
|
||||
}
|
||||
return inputBlockSize - 10;
|
||||
}
|
||||
|
||||
public int GetOutputBlockSize()
|
||||
{
|
||||
int outputBlockSize = engine.GetOutputBlockSize();
|
||||
if (!forEncryption)
|
||||
{
|
||||
return outputBlockSize - 10;
|
||||
}
|
||||
return outputBlockSize;
|
||||
}
|
||||
|
||||
public byte[] ProcessBlock(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (!forEncryption)
|
||||
{
|
||||
return DecodeBlock(input, inOff, length);
|
||||
}
|
||||
return EncodeBlock(input, inOff, length);
|
||||
}
|
||||
|
||||
private byte[] EncodeBlock(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (inLen > GetInputBlockSize())
|
||||
{
|
||||
throw new ArgumentException("input data too large", "inLen");
|
||||
}
|
||||
byte[] array = new byte[engine.GetInputBlockSize()];
|
||||
if (forPrivateKey)
|
||||
{
|
||||
array[0] = 1;
|
||||
for (int i = 1; i != array.Length - inLen - 1; i++)
|
||||
{
|
||||
array[i] = byte.MaxValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
random.NextBytes(array);
|
||||
array[0] = 2;
|
||||
for (int j = 1; j != array.Length - inLen - 1; j++)
|
||||
{
|
||||
while (array[j] == 0)
|
||||
{
|
||||
array[j] = (byte)random.NextInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
array[array.Length - inLen - 1] = 0;
|
||||
Array.Copy(input, inOff, array, array.Length - inLen, inLen);
|
||||
return engine.ProcessBlock(array, 0, array.Length);
|
||||
}
|
||||
|
||||
private static int CheckPkcs1Encoding(byte[] encoded, int pLen)
|
||||
{
|
||||
int num = 0;
|
||||
num |= encoded[0] ^ 2;
|
||||
int num2 = encoded.Length - (pLen + 1);
|
||||
for (int i = 1; i < num2; i++)
|
||||
{
|
||||
int num3 = encoded[i];
|
||||
num3 |= num3 >> 1;
|
||||
num3 |= num3 >> 2;
|
||||
num3 |= num3 >> 4;
|
||||
num |= (num3 & 1) - 1;
|
||||
}
|
||||
num |= encoded[^(pLen + 1)];
|
||||
num |= num >> 1;
|
||||
num |= num >> 2;
|
||||
num |= num >> 4;
|
||||
return ~((num & 1) - 1);
|
||||
}
|
||||
|
||||
private byte[] DecodeBlockOrRandom(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (!forPrivateKey)
|
||||
{
|
||||
throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
|
||||
}
|
||||
byte[] array = engine.ProcessBlock(input, inOff, inLen);
|
||||
byte[] array2;
|
||||
if (fallback == null)
|
||||
{
|
||||
array2 = new byte[pLen];
|
||||
random.NextBytes(array2);
|
||||
}
|
||||
else
|
||||
{
|
||||
array2 = fallback;
|
||||
}
|
||||
byte[] array3 = ((useStrictLength & (array.Length != engine.GetOutputBlockSize())) ? blockBuffer : array);
|
||||
int num = CheckPkcs1Encoding(array3, pLen);
|
||||
byte[] array4 = new byte[pLen];
|
||||
for (int i = 0; i < pLen; i++)
|
||||
{
|
||||
array4[i] = (byte)((array3[i + (array3.Length - pLen)] & ~num) | (array2[i] & num));
|
||||
}
|
||||
Arrays.Fill(array3, 0);
|
||||
return array4;
|
||||
}
|
||||
|
||||
private byte[] DecodeBlock(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (pLen != -1)
|
||||
{
|
||||
return DecodeBlockOrRandom(input, inOff, inLen);
|
||||
}
|
||||
byte[] array = engine.ProcessBlock(input, inOff, inLen);
|
||||
bool flag = useStrictLength & (array.Length != engine.GetOutputBlockSize());
|
||||
byte[] array2 = ((array.Length >= GetOutputBlockSize()) ? array : blockBuffer);
|
||||
byte b = (byte)((!forPrivateKey) ? 1u : 2u);
|
||||
byte b2 = array2[0];
|
||||
bool flag2 = b2 != b;
|
||||
int num = FindStart(b2, array2);
|
||||
num++;
|
||||
if (flag2 || num < 10)
|
||||
{
|
||||
Arrays.Fill(array2, 0);
|
||||
throw new InvalidCipherTextException("block incorrect");
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
Arrays.Fill(array2, 0);
|
||||
throw new InvalidCipherTextException("block incorrect size");
|
||||
}
|
||||
byte[] array3 = new byte[array2.Length - num];
|
||||
Array.Copy(array2, num, array3, 0, array3.Length);
|
||||
return array3;
|
||||
}
|
||||
|
||||
private int FindStart(byte type, byte[] block)
|
||||
{
|
||||
int num = -1;
|
||||
bool flag = false;
|
||||
for (int i = 1; i != block.Length; i++)
|
||||
{
|
||||
byte b = block[i];
|
||||
if (b == 0 && num < 0)
|
||||
{
|
||||
num = i;
|
||||
}
|
||||
flag = flag || (type == 1 && num < 0 && b != byte.MaxValue);
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
return num;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,510 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class AesEngine : IBlockCipher
|
||||
{
|
||||
private const uint m1 = 2155905152u;
|
||||
|
||||
private const uint m2 = 2139062143u;
|
||||
|
||||
private const uint m3 = 27u;
|
||||
|
||||
private const uint m4 = 3233857728u;
|
||||
|
||||
private const uint m5 = 1061109567u;
|
||||
|
||||
private const int BLOCK_SIZE = 16;
|
||||
|
||||
private static readonly byte[] S = new byte[256]
|
||||
{
|
||||
99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
|
||||
103, 43, 254, 215, 171, 118, 202, 130, 201, 125,
|
||||
250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
|
||||
114, 192, 183, 253, 147, 38, 54, 63, 247, 204,
|
||||
52, 165, 229, 241, 113, 216, 49, 21, 4, 199,
|
||||
35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
|
||||
235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
|
||||
90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
|
||||
83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
|
||||
190, 57, 74, 76, 88, 207, 208, 239, 170, 251,
|
||||
67, 77, 51, 133, 69, 249, 2, 127, 80, 60,
|
||||
159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
|
||||
188, 182, 218, 33, 16, 255, 243, 210, 205, 12,
|
||||
19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
|
||||
100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
|
||||
144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
|
||||
224, 50, 58, 10, 73, 6, 36, 92, 194, 211,
|
||||
172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
|
||||
141, 213, 78, 169, 108, 86, 244, 234, 101, 122,
|
||||
174, 8, 186, 120, 37, 46, 28, 166, 180, 198,
|
||||
232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
|
||||
181, 102, 72, 3, 246, 14, 97, 53, 87, 185,
|
||||
134, 193, 29, 158, 225, 248, 152, 17, 105, 217,
|
||||
142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
|
||||
140, 161, 137, 13, 191, 230, 66, 104, 65, 153,
|
||||
45, 15, 176, 84, 187, 22
|
||||
};
|
||||
|
||||
private static readonly byte[] Si = new byte[256]
|
||||
{
|
||||
82, 9, 106, 213, 48, 54, 165, 56, 191, 64,
|
||||
163, 158, 129, 243, 215, 251, 124, 227, 57, 130,
|
||||
155, 47, 255, 135, 52, 142, 67, 68, 196, 222,
|
||||
233, 203, 84, 123, 148, 50, 166, 194, 35, 61,
|
||||
238, 76, 149, 11, 66, 250, 195, 78, 8, 46,
|
||||
161, 102, 40, 217, 36, 178, 118, 91, 162, 73,
|
||||
109, 139, 209, 37, 114, 248, 246, 100, 134, 104,
|
||||
152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
|
||||
108, 112, 72, 80, 253, 237, 185, 218, 94, 21,
|
||||
70, 87, 167, 141, 157, 132, 144, 216, 171, 0,
|
||||
140, 188, 211, 10, 247, 228, 88, 5, 184, 179,
|
||||
69, 6, 208, 44, 30, 143, 202, 63, 15, 2,
|
||||
193, 175, 189, 3, 1, 19, 138, 107, 58, 145,
|
||||
17, 65, 79, 103, 220, 234, 151, 242, 207, 206,
|
||||
240, 180, 230, 115, 150, 172, 116, 34, 231, 173,
|
||||
53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
|
||||
71, 241, 26, 113, 29, 41, 197, 137, 111, 183,
|
||||
98, 14, 170, 24, 190, 27, 252, 86, 62, 75,
|
||||
198, 210, 121, 32, 154, 219, 192, 254, 120, 205,
|
||||
90, 244, 31, 221, 168, 51, 136, 7, 199, 49,
|
||||
177, 18, 16, 89, 39, 128, 236, 95, 96, 81,
|
||||
127, 169, 25, 181, 74, 13, 45, 229, 122, 159,
|
||||
147, 201, 156, 239, 160, 224, 59, 77, 174, 42,
|
||||
245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
|
||||
23, 43, 4, 126, 186, 119, 214, 38, 225, 105,
|
||||
20, 99, 85, 33, 12, 125
|
||||
};
|
||||
|
||||
private static readonly byte[] rcon = new byte[30]
|
||||
{
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 27, 54,
|
||||
108, 216, 171, 77, 154, 47, 94, 188, 99, 198,
|
||||
151, 53, 106, 212, 179, 125, 250, 239, 197, 145
|
||||
};
|
||||
|
||||
private static readonly uint[] T0 = new uint[256]
|
||||
{
|
||||
2774754246u, 2222750968u, 2574743534u, 2373680118u, 234025727u, 3177933782u, 2976870366u, 1422247313u, 1345335392u, 50397442u,
|
||||
2842126286u, 2099981142u, 436141799u, 1658312629u, 3870010189u, 2591454956u, 1170918031u, 2642575903u, 1086966153u, 2273148410u,
|
||||
368769775u, 3948501426u, 3376891790u, 200339707u, 3970805057u, 1742001331u, 4255294047u, 3937382213u, 3214711843u, 4154762323u,
|
||||
2524082916u, 1539358875u, 3266819957u, 486407649u, 2928907069u, 1780885068u, 1513502316u, 1094664062u, 49805301u, 1338821763u,
|
||||
1546925160u, 4104496465u, 887481809u, 150073849u, 2473685474u, 1943591083u, 1395732834u, 1058346282u, 201589768u, 1388824469u,
|
||||
1696801606u, 1589887901u, 672667696u, 2711000631u, 251987210u, 3046808111u, 151455502u, 907153956u, 2608889883u, 1038279391u,
|
||||
652995533u, 1764173646u, 3451040383u, 2675275242u, 453576978u, 2659418909u, 1949051992u, 773462580u, 756751158u, 2993581788u,
|
||||
3998898868u, 4221608027u, 4132590244u, 1295727478u, 1641469623u, 3467883389u, 2066295122u, 1055122397u, 1898917726u, 2542044179u,
|
||||
4115878822u, 1758581177u, 0u, 753790401u, 1612718144u, 536673507u, 3367088505u, 3982187446u, 3194645204u, 1187761037u,
|
||||
3653156455u, 1262041458u, 3729410708u, 3561770136u, 3898103984u, 1255133061u, 1808847035u, 720367557u, 3853167183u, 385612781u,
|
||||
3309519750u, 3612167578u, 1429418854u, 2491778321u, 3477423498u, 284817897u, 100794884u, 2172616702u, 4031795360u, 1144798328u,
|
||||
3131023141u, 3819481163u, 4082192802u, 4272137053u, 3225436288u, 2324664069u, 2912064063u, 3164445985u, 1211644016u, 83228145u,
|
||||
3753688163u, 3249976951u, 1977277103u, 1663115586u, 806359072u, 452984805u, 250868733u, 1842533055u, 1288555905u, 336333848u,
|
||||
890442534u, 804056259u, 3781124030u, 2727843637u, 3427026056u, 957814574u, 1472513171u, 4071073621u, 2189328124u, 1195195770u,
|
||||
2892260552u, 3881655738u, 723065138u, 2507371494u, 2690670784u, 2558624025u, 3511635870u, 2145180835u, 1713513028u, 2116692564u,
|
||||
2878378043u, 2206763019u, 3393603212u, 703524551u, 3552098411u, 1007948840u, 2044649127u, 3797835452u, 487262998u, 1994120109u,
|
||||
1004593371u, 1446130276u, 1312438900u, 503974420u, 3679013266u, 168166924u, 1814307912u, 3831258296u, 1573044895u, 1859376061u,
|
||||
4021070915u, 2791465668u, 2828112185u, 2761266481u, 937747667u, 2339994098u, 854058965u, 1137232011u, 1496790894u, 3077402074u,
|
||||
2358086913u, 1691735473u, 3528347292u, 3769215305u, 3027004632u, 4199962284u, 133494003u, 636152527u, 2942657994u, 2390391540u,
|
||||
3920539207u, 403179536u, 3585784431u, 2289596656u, 1864705354u, 1915629148u, 605822008u, 4054230615u, 3350508659u, 1371981463u,
|
||||
602466507u, 2094914977u, 2624877800u, 555687742u, 3712699286u, 3703422305u, 2257292045u, 2240449039u, 2423288032u, 1111375484u,
|
||||
3300242801u, 2858837708u, 3628615824u, 84083462u, 32962295u, 302911004u, 2741068226u, 1597322602u, 4183250862u, 3501832553u,
|
||||
2441512471u, 1489093017u, 656219450u, 3114180135u, 954327513u, 335083755u, 3013122091u, 856756514u, 3144247762u, 1893325225u,
|
||||
2307821063u, 2811532339u, 3063651117u, 572399164u, 2458355477u, 552200649u, 1238290055u, 4283782570u, 2015897680u, 2061492133u,
|
||||
2408352771u, 4171342169u, 2156497161u, 386731290u, 3669999461u, 837215959u, 3326231172u, 3093850320u, 3275833730u, 2962856233u,
|
||||
1999449434u, 286199582u, 3417354363u, 4233385128u, 3602627437u, 974525996u
|
||||
};
|
||||
|
||||
private static readonly uint[] Tinv0 = new uint[256]
|
||||
{
|
||||
1353184337u, 1399144830u, 3282310938u, 2522752826u, 3412831035u, 4047871263u, 2874735276u, 2466505547u, 1442459680u, 4134368941u,
|
||||
2440481928u, 625738485u, 4242007375u, 3620416197u, 2151953702u, 2409849525u, 1230680542u, 1729870373u, 2551114309u, 3787521629u,
|
||||
41234371u, 317738113u, 2744600205u, 3338261355u, 3881799427u, 2510066197u, 3950669247u, 3663286933u, 763608788u, 3542185048u,
|
||||
694804553u, 1154009486u, 1787413109u, 2021232372u, 1799248025u, 3715217703u, 3058688446u, 397248752u, 1722556617u, 3023752829u,
|
||||
407560035u, 2184256229u, 1613975959u, 1165972322u, 3765920945u, 2226023355u, 480281086u, 2485848313u, 1483229296u, 436028815u,
|
||||
2272059028u, 3086515026u, 601060267u, 3791801202u, 1468997603u, 715871590u, 120122290u, 63092015u, 2591802758u, 2768779219u,
|
||||
4068943920u, 2997206819u, 3127509762u, 1552029421u, 723308426u, 2461301159u, 4042393587u, 2715969870u, 3455375973u, 3586000134u,
|
||||
526529745u, 2331944644u, 2639474228u, 2689987490u, 853641733u, 1978398372u, 971801355u, 2867814464u, 111112542u, 1360031421u,
|
||||
4186579262u, 1023860118u, 2919579357u, 1186850381u, 3045938321u, 90031217u, 1876166148u, 4279586912u, 620468249u, 2548678102u,
|
||||
3426959497u, 2006899047u, 3175278768u, 2290845959u, 945494503u, 3689859193u, 1191869601u, 3910091388u, 3374220536u, 0u,
|
||||
2206629897u, 1223502642u, 2893025566u, 1316117100u, 4227796733u, 1446544655u, 517320253u, 658058550u, 1691946762u, 564550760u,
|
||||
3511966619u, 976107044u, 2976320012u, 266819475u, 3533106868u, 2660342555u, 1338359936u, 2720062561u, 1766553434u, 370807324u,
|
||||
179999714u, 3844776128u, 1138762300u, 488053522u, 185403662u, 2915535858u, 3114841645u, 3366526484u, 2233069911u, 1275557295u,
|
||||
3151862254u, 4250959779u, 2670068215u, 3170202204u, 3309004356u, 880737115u, 1982415755u, 3703972811u, 1761406390u, 1676797112u,
|
||||
3403428311u, 277177154u, 1076008723u, 538035844u, 2099530373u, 4164795346u, 288553390u, 1839278535u, 1261411869u, 4080055004u,
|
||||
3964831245u, 3504587127u, 1813426987u, 2579067049u, 4199060497u, 577038663u, 3297574056u, 440397984u, 3626794326u, 4019204898u,
|
||||
3343796615u, 3251714265u, 4272081548u, 906744984u, 3481400742u, 685669029u, 646887386u, 2764025151u, 3835509292u, 227702864u,
|
||||
2613862250u, 1648787028u, 3256061430u, 3904428176u, 1593260334u, 4121936770u, 3196083615u, 2090061929u, 2838353263u, 3004310991u,
|
||||
999926984u, 2809993232u, 1852021992u, 2075868123u, 158869197u, 4095236462u, 28809964u, 2828685187u, 1701746150u, 2129067946u,
|
||||
147831841u, 3873969647u, 3650873274u, 3459673930u, 3557400554u, 3598495785u, 2947720241u, 824393514u, 815048134u, 3227951669u,
|
||||
935087732u, 2798289660u, 2966458592u, 366520115u, 1251476721u, 4158319681u, 240176511u, 804688151u, 2379631990u, 1303441219u,
|
||||
1414376140u, 3741619940u, 3820343710u, 461924940u, 3089050817u, 2136040774u, 82468509u, 1563790337u, 1937016826u, 776014843u,
|
||||
1511876531u, 1389550482u, 861278441u, 323475053u, 2355222426u, 2047648055u, 2383738969u, 2302415851u, 3995576782u, 902390199u,
|
||||
3991215329u, 1018251130u, 1507840668u, 1064563285u, 2043548696u, 3208103795u, 3939366739u, 1537932639u, 342834655u, 2262516856u,
|
||||
2180231114u, 1053059257u, 741614648u, 1598071746u, 1925389590u, 203809468u, 2336832552u, 1100287487u, 1895934009u, 3736275976u,
|
||||
2632234200u, 2428589668u, 1636092795u, 1890988757u, 1952214088u, 1113045200u
|
||||
};
|
||||
|
||||
private int ROUNDS;
|
||||
|
||||
private uint[][] WorkingKey;
|
||||
|
||||
private uint C0;
|
||||
|
||||
private uint C1;
|
||||
|
||||
private uint C2;
|
||||
|
||||
private uint C3;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
private byte[] s;
|
||||
|
||||
public virtual string AlgorithmName => "AES";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
private static uint Shift(uint r, int shift)
|
||||
{
|
||||
return (r >> shift) | (r << 32 - shift);
|
||||
}
|
||||
|
||||
private static uint FFmulX(uint x)
|
||||
{
|
||||
return ((x & 0x7F7F7F7F) << 1) ^ (((x & 0x80808080u) >> 7) * 27);
|
||||
}
|
||||
|
||||
private static uint FFmulX2(uint x)
|
||||
{
|
||||
uint num = (x & 0x3F3F3F3F) << 2;
|
||||
uint num2 = x & 0xC0C0C0C0u;
|
||||
num2 ^= num2 >> 1;
|
||||
return num ^ (num2 >> 2) ^ (num2 >> 5);
|
||||
}
|
||||
|
||||
private static uint Inv_Mcol(uint x)
|
||||
{
|
||||
uint num = x;
|
||||
uint num2 = num ^ Shift(num, 8);
|
||||
num ^= FFmulX(num2);
|
||||
num2 ^= FFmulX2(num);
|
||||
return num ^ (num2 ^ Shift(num2, 16));
|
||||
}
|
||||
|
||||
private static uint SubWord(uint x)
|
||||
{
|
||||
return (uint)(S[x & 0xFF] | (S[(x >> 8) & 0xFF] << 8) | (S[(x >> 16) & 0xFF] << 16) | (S[(x >> 24) & 0xFF] << 24));
|
||||
}
|
||||
|
||||
private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption)
|
||||
{
|
||||
int num = key.Length;
|
||||
if (num < 16 || num > 32 || (num & 7) != 0)
|
||||
{
|
||||
throw new ArgumentException("Key length not 128/192/256 bits.");
|
||||
}
|
||||
int num2 = num >> 2;
|
||||
ROUNDS = num2 + 6;
|
||||
uint[][] array = new uint[ROUNDS + 1][];
|
||||
for (int i = 0; i <= ROUNDS; i++)
|
||||
{
|
||||
array[i] = new uint[4];
|
||||
}
|
||||
switch (num2)
|
||||
{
|
||||
case 4:
|
||||
{
|
||||
uint num21 = Pack.LE_To_UInt32(key, 0);
|
||||
array[0][0] = num21;
|
||||
uint num22 = Pack.LE_To_UInt32(key, 4);
|
||||
array[0][1] = num22;
|
||||
uint num23 = Pack.LE_To_UInt32(key, 8);
|
||||
array[0][2] = num23;
|
||||
uint num24 = Pack.LE_To_UInt32(key, 12);
|
||||
array[0][3] = num24;
|
||||
for (int l = 1; l <= 10; l++)
|
||||
{
|
||||
uint num25 = SubWord(Shift(num24, 8)) ^ rcon[l - 1];
|
||||
num21 ^= num25;
|
||||
array[l][0] = num21;
|
||||
num22 ^= num21;
|
||||
array[l][1] = num22;
|
||||
num23 ^= num22;
|
||||
array[l][2] = num23;
|
||||
num24 ^= num23;
|
||||
array[l][3] = num24;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
uint num13 = Pack.LE_To_UInt32(key, 0);
|
||||
array[0][0] = num13;
|
||||
uint num14 = Pack.LE_To_UInt32(key, 4);
|
||||
array[0][1] = num14;
|
||||
uint num15 = Pack.LE_To_UInt32(key, 8);
|
||||
array[0][2] = num15;
|
||||
uint num16 = Pack.LE_To_UInt32(key, 12);
|
||||
array[0][3] = num16;
|
||||
uint num17 = Pack.LE_To_UInt32(key, 16);
|
||||
array[1][0] = num17;
|
||||
uint num18 = Pack.LE_To_UInt32(key, 20);
|
||||
array[1][1] = num18;
|
||||
uint num19 = 1u;
|
||||
uint num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num19 <<= 1;
|
||||
num13 ^= num20;
|
||||
array[1][2] = num13;
|
||||
num14 ^= num13;
|
||||
array[1][3] = num14;
|
||||
num15 ^= num14;
|
||||
array[2][0] = num15;
|
||||
num16 ^= num15;
|
||||
array[2][1] = num16;
|
||||
num17 ^= num16;
|
||||
array[2][2] = num17;
|
||||
num18 ^= num17;
|
||||
array[2][3] = num18;
|
||||
for (int k = 3; k < 12; k += 3)
|
||||
{
|
||||
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num19 <<= 1;
|
||||
num13 ^= num20;
|
||||
array[k][0] = num13;
|
||||
num14 ^= num13;
|
||||
array[k][1] = num14;
|
||||
num15 ^= num14;
|
||||
array[k][2] = num15;
|
||||
num16 ^= num15;
|
||||
array[k][3] = num16;
|
||||
num17 ^= num16;
|
||||
array[k + 1][0] = num17;
|
||||
num18 ^= num17;
|
||||
array[k + 1][1] = num18;
|
||||
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num19 <<= 1;
|
||||
num13 ^= num20;
|
||||
array[k + 1][2] = num13;
|
||||
num14 ^= num13;
|
||||
array[k + 1][3] = num14;
|
||||
num15 ^= num14;
|
||||
array[k + 2][0] = num15;
|
||||
num16 ^= num15;
|
||||
array[k + 2][1] = num16;
|
||||
num17 ^= num16;
|
||||
array[k + 2][2] = num17;
|
||||
num18 ^= num17;
|
||||
array[k + 2][3] = num18;
|
||||
}
|
||||
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num13 ^= num20;
|
||||
array[12][0] = num13;
|
||||
num14 ^= num13;
|
||||
array[12][1] = num14;
|
||||
num15 ^= num14;
|
||||
array[12][2] = num15;
|
||||
num16 ^= num15;
|
||||
array[12][3] = num16;
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
uint num3 = Pack.LE_To_UInt32(key, 0);
|
||||
array[0][0] = num3;
|
||||
uint num4 = Pack.LE_To_UInt32(key, 4);
|
||||
array[0][1] = num4;
|
||||
uint num5 = Pack.LE_To_UInt32(key, 8);
|
||||
array[0][2] = num5;
|
||||
uint num6 = Pack.LE_To_UInt32(key, 12);
|
||||
array[0][3] = num6;
|
||||
uint num7 = Pack.LE_To_UInt32(key, 16);
|
||||
array[1][0] = num7;
|
||||
uint num8 = Pack.LE_To_UInt32(key, 20);
|
||||
array[1][1] = num8;
|
||||
uint num9 = Pack.LE_To_UInt32(key, 24);
|
||||
array[1][2] = num9;
|
||||
uint num10 = Pack.LE_To_UInt32(key, 28);
|
||||
array[1][3] = num10;
|
||||
uint num11 = 1u;
|
||||
uint num12;
|
||||
for (int j = 2; j < 14; j += 2)
|
||||
{
|
||||
num12 = SubWord(Shift(num10, 8)) ^ num11;
|
||||
num11 <<= 1;
|
||||
num3 ^= num12;
|
||||
array[j][0] = num3;
|
||||
num4 ^= num3;
|
||||
array[j][1] = num4;
|
||||
num5 ^= num4;
|
||||
array[j][2] = num5;
|
||||
num6 ^= num5;
|
||||
array[j][3] = num6;
|
||||
num12 = SubWord(num6);
|
||||
num7 ^= num12;
|
||||
array[j + 1][0] = num7;
|
||||
num8 ^= num7;
|
||||
array[j + 1][1] = num8;
|
||||
num9 ^= num8;
|
||||
array[j + 1][2] = num9;
|
||||
num10 ^= num9;
|
||||
array[j + 1][3] = num10;
|
||||
}
|
||||
num12 = SubWord(Shift(num10, 8)) ^ num11;
|
||||
num3 ^= num12;
|
||||
array[14][0] = num3;
|
||||
num4 ^= num3;
|
||||
array[14][1] = num4;
|
||||
num5 ^= num4;
|
||||
array[14][2] = num5;
|
||||
num6 ^= num5;
|
||||
array[14][3] = num6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException("Should never get here");
|
||||
}
|
||||
if (!forEncryption)
|
||||
{
|
||||
for (int m = 1; m < ROUNDS; m++)
|
||||
{
|
||||
uint[] array2 = array[m];
|
||||
for (int n = 0; n < 4; n++)
|
||||
{
|
||||
array2[n] = Inv_Mcol(array2[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter keyParameter))
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to AES init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption);
|
||||
this.forEncryption = forEncryption;
|
||||
s = Arrays.Clone(forEncryption ? S : Si);
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (WorkingKey == null)
|
||||
{
|
||||
throw new InvalidOperationException("AES engine not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 16, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 16, "output buffer too short");
|
||||
UnPackBlock(input, inOff);
|
||||
if (forEncryption)
|
||||
{
|
||||
EncryptBlock(WorkingKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
DecryptBlock(WorkingKey);
|
||||
}
|
||||
PackBlock(output, outOff);
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
private void UnPackBlock(byte[] bytes, int off)
|
||||
{
|
||||
C0 = Pack.LE_To_UInt32(bytes, off);
|
||||
C1 = Pack.LE_To_UInt32(bytes, off + 4);
|
||||
C2 = Pack.LE_To_UInt32(bytes, off + 8);
|
||||
C3 = Pack.LE_To_UInt32(bytes, off + 12);
|
||||
}
|
||||
|
||||
private void PackBlock(byte[] bytes, int off)
|
||||
{
|
||||
Pack.UInt32_To_LE(C0, bytes, off);
|
||||
Pack.UInt32_To_LE(C1, bytes, off + 4);
|
||||
Pack.UInt32_To_LE(C2, bytes, off + 8);
|
||||
Pack.UInt32_To_LE(C3, bytes, off + 12);
|
||||
}
|
||||
|
||||
private void EncryptBlock(uint[][] KW)
|
||||
{
|
||||
uint[] array = KW[0];
|
||||
uint num = C0 ^ array[0];
|
||||
uint num2 = C1 ^ array[1];
|
||||
uint num3 = C2 ^ array[2];
|
||||
uint num4 = C3 ^ array[3];
|
||||
int num5 = 1;
|
||||
uint num6;
|
||||
uint num7;
|
||||
uint num8;
|
||||
while (num5 < ROUNDS - 1)
|
||||
{
|
||||
array = KW[num5++];
|
||||
num6 = T0[num & 0xFF] ^ Shift(T0[(num2 >> 8) & 0xFF], 24) ^ Shift(T0[(num3 >> 16) & 0xFF], 16) ^ Shift(T0[(num4 >> 24) & 0xFF], 8) ^ array[0];
|
||||
num7 = T0[num2 & 0xFF] ^ Shift(T0[(num3 >> 8) & 0xFF], 24) ^ Shift(T0[(num4 >> 16) & 0xFF], 16) ^ Shift(T0[(num >> 24) & 0xFF], 8) ^ array[1];
|
||||
num8 = T0[num3 & 0xFF] ^ Shift(T0[(num4 >> 8) & 0xFF], 24) ^ Shift(T0[(num >> 16) & 0xFF], 16) ^ Shift(T0[(num2 >> 24) & 0xFF], 8) ^ array[2];
|
||||
num4 = T0[num4 & 0xFF] ^ Shift(T0[(num >> 8) & 0xFF], 24) ^ Shift(T0[(num2 >> 16) & 0xFF], 16) ^ Shift(T0[(num3 >> 24) & 0xFF], 8) ^ array[3];
|
||||
array = KW[num5++];
|
||||
num = T0[num6 & 0xFF] ^ Shift(T0[(num7 >> 8) & 0xFF], 24) ^ Shift(T0[(num8 >> 16) & 0xFF], 16) ^ Shift(T0[(num4 >> 24) & 0xFF], 8) ^ array[0];
|
||||
num2 = T0[num7 & 0xFF] ^ Shift(T0[(num8 >> 8) & 0xFF], 24) ^ Shift(T0[(num4 >> 16) & 0xFF], 16) ^ Shift(T0[(num6 >> 24) & 0xFF], 8) ^ array[1];
|
||||
num3 = T0[num8 & 0xFF] ^ Shift(T0[(num4 >> 8) & 0xFF], 24) ^ Shift(T0[(num6 >> 16) & 0xFF], 16) ^ Shift(T0[(num7 >> 24) & 0xFF], 8) ^ array[2];
|
||||
num4 = T0[num4 & 0xFF] ^ Shift(T0[(num6 >> 8) & 0xFF], 24) ^ Shift(T0[(num7 >> 16) & 0xFF], 16) ^ Shift(T0[(num8 >> 24) & 0xFF], 8) ^ array[3];
|
||||
}
|
||||
array = KW[num5++];
|
||||
num6 = T0[num & 0xFF] ^ Shift(T0[(num2 >> 8) & 0xFF], 24) ^ Shift(T0[(num3 >> 16) & 0xFF], 16) ^ Shift(T0[(num4 >> 24) & 0xFF], 8) ^ array[0];
|
||||
num7 = T0[num2 & 0xFF] ^ Shift(T0[(num3 >> 8) & 0xFF], 24) ^ Shift(T0[(num4 >> 16) & 0xFF], 16) ^ Shift(T0[(num >> 24) & 0xFF], 8) ^ array[1];
|
||||
num8 = T0[num3 & 0xFF] ^ Shift(T0[(num4 >> 8) & 0xFF], 24) ^ Shift(T0[(num >> 16) & 0xFF], 16) ^ Shift(T0[(num2 >> 24) & 0xFF], 8) ^ array[2];
|
||||
num4 = T0[num4 & 0xFF] ^ Shift(T0[(num >> 8) & 0xFF], 24) ^ Shift(T0[(num2 >> 16) & 0xFF], 16) ^ Shift(T0[(num3 >> 24) & 0xFF], 8) ^ array[3];
|
||||
array = KW[num5];
|
||||
C0 = (uint)(S[num6 & 0xFF] ^ (S[(num7 >> 8) & 0xFF] << 8) ^ (s[(num8 >> 16) & 0xFF] << 16) ^ (s[(num4 >> 24) & 0xFF] << 24)) ^ array[0];
|
||||
C1 = (uint)(s[num7 & 0xFF] ^ (S[(num8 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (s[(num6 >> 24) & 0xFF] << 24)) ^ array[1];
|
||||
C2 = (uint)(s[num8 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num6 >> 16) & 0xFF] << 16) ^ (S[(num7 >> 24) & 0xFF] << 24)) ^ array[2];
|
||||
C3 = (uint)(s[num4 & 0xFF] ^ (s[(num6 >> 8) & 0xFF] << 8) ^ (s[(num7 >> 16) & 0xFF] << 16) ^ (S[(num8 >> 24) & 0xFF] << 24)) ^ array[3];
|
||||
}
|
||||
|
||||
private void DecryptBlock(uint[][] KW)
|
||||
{
|
||||
uint[] array = KW[ROUNDS];
|
||||
uint num = C0 ^ array[0];
|
||||
uint num2 = C1 ^ array[1];
|
||||
uint num3 = C2 ^ array[2];
|
||||
uint num4 = C3 ^ array[3];
|
||||
int num5 = ROUNDS - 1;
|
||||
uint num6;
|
||||
uint num7;
|
||||
uint num8;
|
||||
while (num5 > 1)
|
||||
{
|
||||
array = KW[num5--];
|
||||
num6 = Tinv0[num & 0xFF] ^ Shift(Tinv0[(num4 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num3 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num2 >> 24) & 0xFF], 8) ^ array[0];
|
||||
num7 = Tinv0[num2 & 0xFF] ^ Shift(Tinv0[(num >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num4 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num3 >> 24) & 0xFF], 8) ^ array[1];
|
||||
num8 = Tinv0[num3 & 0xFF] ^ Shift(Tinv0[(num2 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num4 >> 24) & 0xFF], 8) ^ array[2];
|
||||
num4 = Tinv0[num4 & 0xFF] ^ Shift(Tinv0[(num3 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num2 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num >> 24) & 0xFF], 8) ^ array[3];
|
||||
array = KW[num5--];
|
||||
num = Tinv0[num6 & 0xFF] ^ Shift(Tinv0[(num4 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num8 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num7 >> 24) & 0xFF], 8) ^ array[0];
|
||||
num2 = Tinv0[num7 & 0xFF] ^ Shift(Tinv0[(num6 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num4 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num8 >> 24) & 0xFF], 8) ^ array[1];
|
||||
num3 = Tinv0[num8 & 0xFF] ^ Shift(Tinv0[(num7 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num6 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num4 >> 24) & 0xFF], 8) ^ array[2];
|
||||
num4 = Tinv0[num4 & 0xFF] ^ Shift(Tinv0[(num8 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num7 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num6 >> 24) & 0xFF], 8) ^ array[3];
|
||||
}
|
||||
array = KW[1];
|
||||
num6 = Tinv0[num & 0xFF] ^ Shift(Tinv0[(num4 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num3 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num2 >> 24) & 0xFF], 8) ^ array[0];
|
||||
num7 = Tinv0[num2 & 0xFF] ^ Shift(Tinv0[(num >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num4 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num3 >> 24) & 0xFF], 8) ^ array[1];
|
||||
num8 = Tinv0[num3 & 0xFF] ^ Shift(Tinv0[(num2 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num4 >> 24) & 0xFF], 8) ^ array[2];
|
||||
num4 = Tinv0[num4 & 0xFF] ^ Shift(Tinv0[(num3 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num2 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num >> 24) & 0xFF], 8) ^ array[3];
|
||||
array = KW[0];
|
||||
C0 = (uint)(Si[num6 & 0xFF] ^ (s[(num4 >> 8) & 0xFF] << 8) ^ (s[(num8 >> 16) & 0xFF] << 16) ^ (Si[(num7 >> 24) & 0xFF] << 24)) ^ array[0];
|
||||
C1 = (uint)(s[num7 & 0xFF] ^ (s[(num6 >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (s[(num8 >> 24) & 0xFF] << 24)) ^ array[1];
|
||||
C2 = (uint)(s[num8 & 0xFF] ^ (Si[(num7 >> 8) & 0xFF] << 8) ^ (Si[(num6 >> 16) & 0xFF] << 16) ^ (s[(num4 >> 24) & 0xFF] << 24)) ^ array[2];
|
||||
C3 = (uint)(Si[num4 & 0xFF] ^ (s[(num8 >> 8) & 0xFF] << 8) ^ (s[(num7 >> 16) & 0xFF] << 16) ^ (s[(num6 >> 24) & 0xFF] << 24)) ^ array[3];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,688 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
[Obsolete("Use AesEngine instead")]
|
||||
public class AesFastEngine : IBlockCipher
|
||||
{
|
||||
private const uint m1 = 2155905152u;
|
||||
|
||||
private const uint m2 = 2139062143u;
|
||||
|
||||
private const uint m3 = 27u;
|
||||
|
||||
private const uint m4 = 3233857728u;
|
||||
|
||||
private const uint m5 = 1061109567u;
|
||||
|
||||
private const int BLOCK_SIZE = 16;
|
||||
|
||||
private static readonly byte[] S = new byte[256]
|
||||
{
|
||||
99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
|
||||
103, 43, 254, 215, 171, 118, 202, 130, 201, 125,
|
||||
250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
|
||||
114, 192, 183, 253, 147, 38, 54, 63, 247, 204,
|
||||
52, 165, 229, 241, 113, 216, 49, 21, 4, 199,
|
||||
35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
|
||||
235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
|
||||
90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
|
||||
83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
|
||||
190, 57, 74, 76, 88, 207, 208, 239, 170, 251,
|
||||
67, 77, 51, 133, 69, 249, 2, 127, 80, 60,
|
||||
159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
|
||||
188, 182, 218, 33, 16, 255, 243, 210, 205, 12,
|
||||
19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
|
||||
100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
|
||||
144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
|
||||
224, 50, 58, 10, 73, 6, 36, 92, 194, 211,
|
||||
172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
|
||||
141, 213, 78, 169, 108, 86, 244, 234, 101, 122,
|
||||
174, 8, 186, 120, 37, 46, 28, 166, 180, 198,
|
||||
232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
|
||||
181, 102, 72, 3, 246, 14, 97, 53, 87, 185,
|
||||
134, 193, 29, 158, 225, 248, 152, 17, 105, 217,
|
||||
142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
|
||||
140, 161, 137, 13, 191, 230, 66, 104, 65, 153,
|
||||
45, 15, 176, 84, 187, 22
|
||||
};
|
||||
|
||||
private static readonly byte[] Si = new byte[256]
|
||||
{
|
||||
82, 9, 106, 213, 48, 54, 165, 56, 191, 64,
|
||||
163, 158, 129, 243, 215, 251, 124, 227, 57, 130,
|
||||
155, 47, 255, 135, 52, 142, 67, 68, 196, 222,
|
||||
233, 203, 84, 123, 148, 50, 166, 194, 35, 61,
|
||||
238, 76, 149, 11, 66, 250, 195, 78, 8, 46,
|
||||
161, 102, 40, 217, 36, 178, 118, 91, 162, 73,
|
||||
109, 139, 209, 37, 114, 248, 246, 100, 134, 104,
|
||||
152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
|
||||
108, 112, 72, 80, 253, 237, 185, 218, 94, 21,
|
||||
70, 87, 167, 141, 157, 132, 144, 216, 171, 0,
|
||||
140, 188, 211, 10, 247, 228, 88, 5, 184, 179,
|
||||
69, 6, 208, 44, 30, 143, 202, 63, 15, 2,
|
||||
193, 175, 189, 3, 1, 19, 138, 107, 58, 145,
|
||||
17, 65, 79, 103, 220, 234, 151, 242, 207, 206,
|
||||
240, 180, 230, 115, 150, 172, 116, 34, 231, 173,
|
||||
53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
|
||||
71, 241, 26, 113, 29, 41, 197, 137, 111, 183,
|
||||
98, 14, 170, 24, 190, 27, 252, 86, 62, 75,
|
||||
198, 210, 121, 32, 154, 219, 192, 254, 120, 205,
|
||||
90, 244, 31, 221, 168, 51, 136, 7, 199, 49,
|
||||
177, 18, 16, 89, 39, 128, 236, 95, 96, 81,
|
||||
127, 169, 25, 181, 74, 13, 45, 229, 122, 159,
|
||||
147, 201, 156, 239, 160, 224, 59, 77, 174, 42,
|
||||
245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
|
||||
23, 43, 4, 126, 186, 119, 214, 38, 225, 105,
|
||||
20, 99, 85, 33, 12, 125
|
||||
};
|
||||
|
||||
private static readonly byte[] rcon = new byte[30]
|
||||
{
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 27, 54,
|
||||
108, 216, 171, 77, 154, 47, 94, 188, 99, 198,
|
||||
151, 53, 106, 212, 179, 125, 250, 239, 197, 145
|
||||
};
|
||||
|
||||
private static readonly uint[] T0 = new uint[256]
|
||||
{
|
||||
2774754246u, 2222750968u, 2574743534u, 2373680118u, 234025727u, 3177933782u, 2976870366u, 1422247313u, 1345335392u, 50397442u,
|
||||
2842126286u, 2099981142u, 436141799u, 1658312629u, 3870010189u, 2591454956u, 1170918031u, 2642575903u, 1086966153u, 2273148410u,
|
||||
368769775u, 3948501426u, 3376891790u, 200339707u, 3970805057u, 1742001331u, 4255294047u, 3937382213u, 3214711843u, 4154762323u,
|
||||
2524082916u, 1539358875u, 3266819957u, 486407649u, 2928907069u, 1780885068u, 1513502316u, 1094664062u, 49805301u, 1338821763u,
|
||||
1546925160u, 4104496465u, 887481809u, 150073849u, 2473685474u, 1943591083u, 1395732834u, 1058346282u, 201589768u, 1388824469u,
|
||||
1696801606u, 1589887901u, 672667696u, 2711000631u, 251987210u, 3046808111u, 151455502u, 907153956u, 2608889883u, 1038279391u,
|
||||
652995533u, 1764173646u, 3451040383u, 2675275242u, 453576978u, 2659418909u, 1949051992u, 773462580u, 756751158u, 2993581788u,
|
||||
3998898868u, 4221608027u, 4132590244u, 1295727478u, 1641469623u, 3467883389u, 2066295122u, 1055122397u, 1898917726u, 2542044179u,
|
||||
4115878822u, 1758581177u, 0u, 753790401u, 1612718144u, 536673507u, 3367088505u, 3982187446u, 3194645204u, 1187761037u,
|
||||
3653156455u, 1262041458u, 3729410708u, 3561770136u, 3898103984u, 1255133061u, 1808847035u, 720367557u, 3853167183u, 385612781u,
|
||||
3309519750u, 3612167578u, 1429418854u, 2491778321u, 3477423498u, 284817897u, 100794884u, 2172616702u, 4031795360u, 1144798328u,
|
||||
3131023141u, 3819481163u, 4082192802u, 4272137053u, 3225436288u, 2324664069u, 2912064063u, 3164445985u, 1211644016u, 83228145u,
|
||||
3753688163u, 3249976951u, 1977277103u, 1663115586u, 806359072u, 452984805u, 250868733u, 1842533055u, 1288555905u, 336333848u,
|
||||
890442534u, 804056259u, 3781124030u, 2727843637u, 3427026056u, 957814574u, 1472513171u, 4071073621u, 2189328124u, 1195195770u,
|
||||
2892260552u, 3881655738u, 723065138u, 2507371494u, 2690670784u, 2558624025u, 3511635870u, 2145180835u, 1713513028u, 2116692564u,
|
||||
2878378043u, 2206763019u, 3393603212u, 703524551u, 3552098411u, 1007948840u, 2044649127u, 3797835452u, 487262998u, 1994120109u,
|
||||
1004593371u, 1446130276u, 1312438900u, 503974420u, 3679013266u, 168166924u, 1814307912u, 3831258296u, 1573044895u, 1859376061u,
|
||||
4021070915u, 2791465668u, 2828112185u, 2761266481u, 937747667u, 2339994098u, 854058965u, 1137232011u, 1496790894u, 3077402074u,
|
||||
2358086913u, 1691735473u, 3528347292u, 3769215305u, 3027004632u, 4199962284u, 133494003u, 636152527u, 2942657994u, 2390391540u,
|
||||
3920539207u, 403179536u, 3585784431u, 2289596656u, 1864705354u, 1915629148u, 605822008u, 4054230615u, 3350508659u, 1371981463u,
|
||||
602466507u, 2094914977u, 2624877800u, 555687742u, 3712699286u, 3703422305u, 2257292045u, 2240449039u, 2423288032u, 1111375484u,
|
||||
3300242801u, 2858837708u, 3628615824u, 84083462u, 32962295u, 302911004u, 2741068226u, 1597322602u, 4183250862u, 3501832553u,
|
||||
2441512471u, 1489093017u, 656219450u, 3114180135u, 954327513u, 335083755u, 3013122091u, 856756514u, 3144247762u, 1893325225u,
|
||||
2307821063u, 2811532339u, 3063651117u, 572399164u, 2458355477u, 552200649u, 1238290055u, 4283782570u, 2015897680u, 2061492133u,
|
||||
2408352771u, 4171342169u, 2156497161u, 386731290u, 3669999461u, 837215959u, 3326231172u, 3093850320u, 3275833730u, 2962856233u,
|
||||
1999449434u, 286199582u, 3417354363u, 4233385128u, 3602627437u, 974525996u
|
||||
};
|
||||
|
||||
private static readonly uint[] T1 = new uint[256]
|
||||
{
|
||||
1667483301u, 2088564868u, 2004348569u, 2071721613u, 4076011277u, 1802229437u, 1869602481u, 3318059348u, 808476752u, 16843267u,
|
||||
1734856361u, 724260477u, 4278118169u, 3621238114u, 2880130534u, 1987505306u, 3402272581u, 2189565853u, 3385428288u, 2105408135u,
|
||||
4210749205u, 1499050731u, 1195871945u, 4042324747u, 2913812972u, 3570709351u, 2728550397u, 2947499498u, 2627478463u, 2762232823u,
|
||||
1920132246u, 3233848155u, 3082253762u, 4261273884u, 2475900334u, 640044138u, 909536346u, 1061125697u, 4160222466u, 3435955023u,
|
||||
875849820u, 2779075060u, 3857043764u, 4059166984u, 1903288979u, 3638078323u, 825320019u, 353708607u, 67373068u, 3351745874u,
|
||||
589514341u, 3284376926u, 404238376u, 2526427041u, 84216335u, 2593796021u, 117902857u, 303178806u, 2155879323u, 3806519101u,
|
||||
3958099238u, 656887401u, 2998042573u, 1970662047u, 151589403u, 2206408094u, 741103732u, 437924910u, 454768173u, 1852759218u,
|
||||
1515893998u, 2694863867u, 1381147894u, 993752653u, 3604395873u, 3014884814u, 690573947u, 3823361342u, 791633521u, 2223248279u,
|
||||
1397991157u, 3520182632u, 0u, 3991781676u, 538984544u, 4244431647u, 2981198280u, 1532737261u, 1785386174u, 3419114822u,
|
||||
3200149465u, 960066123u, 1246401758u, 1280088276u, 1482207464u, 3486483786u, 3503340395u, 4025468202u, 2863288293u, 4227591446u,
|
||||
1128498885u, 1296931543u, 859006549u, 2240090516u, 1162185423u, 4193904912u, 33686534u, 2139094657u, 1347461360u, 1010595908u,
|
||||
2678007226u, 2829601763u, 1364304627u, 2745392638u, 1077969088u, 2408514954u, 2459058093u, 2644320700u, 943222856u, 4126535940u,
|
||||
3166462943u, 3065411521u, 3671764853u, 555827811u, 269492272u, 4294960410u, 4092853518u, 3537026925u, 3452797260u, 202119188u,
|
||||
320022069u, 3974939439u, 1600110305u, 2543269282u, 1145342156u, 387395129u, 3301217111u, 2812761586u, 2122251394u, 1027439175u,
|
||||
1684326572u, 1566423783u, 421081643u, 1936975509u, 1616953504u, 2172721560u, 1330618065u, 3705447295u, 572671078u, 707417214u,
|
||||
2425371563u, 2290617219u, 1179028682u, 4008625961u, 3099093971u, 336865340u, 3739133817u, 1583267042u, 185275933u, 3688607094u,
|
||||
3772832571u, 842163286u, 976909390u, 168432670u, 1229558491u, 101059594u, 606357612u, 1549580516u, 3267534685u, 3553869166u,
|
||||
2896970735u, 1650640038u, 2442213800u, 2509582756u, 3840201527u, 2038035083u, 3890730290u, 3368586051u, 926379609u, 1835915959u,
|
||||
2374828428u, 3587551588u, 1313774802u, 2846444000u, 1819072692u, 1448520954u, 4109693703u, 3941256997u, 1701169839u, 2054878350u,
|
||||
2930657257u, 134746136u, 3132780501u, 2021191816u, 623200879u, 774790258u, 471611428u, 2795919345u, 3031724999u, 3334903633u,
|
||||
3907570467u, 3722289532u, 1953818780u, 522141217u, 1263245021u, 3183305180u, 2341145990u, 2324303749u, 1886445712u, 1044282434u,
|
||||
3048567236u, 1718013098u, 1212715224u, 50529797u, 4143380225u, 235805714u, 1633796771u, 892693087u, 1465364217u, 3115936208u,
|
||||
2256934801u, 3250690392u, 488454695u, 2661164985u, 3789674808u, 4177062675u, 2560109491u, 286335539u, 1768542907u, 3654920560u,
|
||||
2391672713u, 2492740519u, 2610638262u, 505297954u, 2273777042u, 3924412704u, 3469641545u, 1431677695u, 673730680u, 3755976058u,
|
||||
2357986191u, 2711706104u, 2307459456u, 218962455u, 3216991706u, 3873888049u, 1111655622u, 1751699640u, 1094812355u, 2576951728u,
|
||||
757946999u, 252648977u, 2964356043u, 1414834428u, 3149622742u, 370551866u
|
||||
};
|
||||
|
||||
private static readonly uint[] T2 = new uint[256]
|
||||
{
|
||||
1673962851u, 2096661628u, 2012125559u, 2079755643u, 4076801522u, 1809235307u, 1876865391u, 3314635973u, 811618352u, 16909057u,
|
||||
1741597031u, 727088427u, 4276558334u, 3618988759u, 2874009259u, 1995217526u, 3398387146u, 2183110018u, 3381215433u, 2113570685u,
|
||||
4209972730u, 1504897881u, 1200539975u, 4042984432u, 2906778797u, 3568527316u, 2724199842u, 2940594863u, 2619588508u, 2756966308u,
|
||||
1927583346u, 3231407040u, 3077948087u, 4259388669u, 2470293139u, 642542118u, 913070646u, 1065238847u, 4160029431u, 3431157708u,
|
||||
879254580u, 2773611685u, 3855693029u, 4059629809u, 1910674289u, 3635114968u, 828527409u, 355090197u, 67636228u, 3348452039u,
|
||||
591815971u, 3281870531u, 405809176u, 2520228246u, 84545285u, 2586817946u, 118360327u, 304363026u, 2149292928u, 3806281186u,
|
||||
3956090603u, 659450151u, 2994720178u, 1978310517u, 152181513u, 2199756419u, 743994412u, 439627290u, 456535323u, 1859957358u,
|
||||
1521806938u, 2690382752u, 1386542674u, 997608763u, 3602342358u, 3011366579u, 693271337u, 3822927587u, 794718511u, 2215876484u,
|
||||
1403450707u, 3518589137u, 0u, 3988860141u, 541089824u, 4242743292u, 2977548465u, 1538714971u, 1792327274u, 3415033547u,
|
||||
3194476990u, 963791673u, 1251270218u, 1285084236u, 1487988824u, 3481619151u, 3501943760u, 4022676207u, 2857362858u, 4226619131u,
|
||||
1132905795u, 1301993293u, 862344499u, 2232521861u, 1166724933u, 4192801017u, 33818114u, 2147385727u, 1352724560u, 1014514748u,
|
||||
2670049951u, 2823545768u, 1369633617u, 2740846243u, 1082179648u, 2399505039u, 2453646738u, 2636233885u, 946882616u, 4126213365u,
|
||||
3160661948u, 3061301686u, 3668932058u, 557998881u, 270544912u, 4293204735u, 4093447923u, 3535760850u, 3447803085u, 202904588u,
|
||||
321271059u, 3972214764u, 1606345055u, 2536874647u, 1149815876u, 388905239u, 3297990596u, 2807427751u, 2130477694u, 1031423805u,
|
||||
1690872932u, 1572530013u, 422718233u, 1944491379u, 1623236704u, 2165938305u, 1335808335u, 3701702620u, 574907938u, 710180394u,
|
||||
2419829648u, 2282455944u, 1183631942u, 4006029806u, 3094074296u, 338181140u, 3735517662u, 1589437022u, 185998603u, 3685578459u,
|
||||
3772464096u, 845436466u, 980700730u, 169090570u, 1234361161u, 101452294u, 608726052u, 1555620956u, 3265224130u, 3552407251u,
|
||||
2890133420u, 1657054818u, 2436475025u, 2503058581u, 3839047652u, 2045938553u, 3889509095u, 3364570056u, 929978679u, 1843050349u,
|
||||
2365688973u, 3585172693u, 1318900302u, 2840191145u, 1826141292u, 1454176854u, 4109567988u, 3939444202u, 1707781989u, 2062847610u,
|
||||
2923948462u, 135272456u, 3127891386u, 2029029496u, 625635109u, 777810478u, 473441308u, 2790781350u, 3027486644u, 3331805638u,
|
||||
3905627112u, 3718347997u, 1961401460u, 524165407u, 1268178251u, 3177307325u, 2332919435u, 2316273034u, 1893765232u, 1048330814u,
|
||||
3044132021u, 1724688998u, 1217452104u, 50726147u, 4143383030u, 236720654u, 1640145761u, 896163637u, 1471084887u, 3110719673u,
|
||||
2249691526u, 3248052417u, 490350365u, 2653403550u, 3789109473u, 4176155640u, 2553000856u, 287453969u, 1775418217u, 3651760345u,
|
||||
2382858638u, 2486413204u, 2603464347u, 507257374u, 2266337927u, 3922272489u, 3464972750u, 1437269845u, 676362280u, 3752164063u,
|
||||
2349043596u, 2707028129u, 2299101321u, 219813645u, 3211123391u, 3872862694u, 1115997762u, 1758509160u, 1099088705u, 2569646233u,
|
||||
760903469u, 253628687u, 2960903088u, 1420360788u, 3144537787u, 371997206u
|
||||
};
|
||||
|
||||
private static readonly uint[] T3 = new uint[256]
|
||||
{
|
||||
3332727651u, 4169432188u, 4003034999u, 4136467323u, 4279104242u, 3602738027u, 3736170351u, 2438251973u, 1615867952u, 33751297u,
|
||||
3467208551u, 1451043627u, 3877240574u, 3043153879u, 1306962859u, 3969545846u, 2403715786u, 530416258u, 2302724553u, 4203183485u,
|
||||
4011195130u, 3001768281u, 2395555655u, 4211863792u, 1106029997u, 3009926356u, 1610457762u, 1173008303u, 599760028u, 1408738468u,
|
||||
3835064946u, 2606481600u, 1975695287u, 3776773629u, 1034851219u, 1282024998u, 1817851446u, 2118205247u, 4110612471u, 2203045068u,
|
||||
1750873140u, 1374987685u, 3509904869u, 4178113009u, 3801313649u, 2876496088u, 1649619249u, 708777237u, 135005188u, 2505230279u,
|
||||
1181033251u, 2640233411u, 807933976u, 933336726u, 168756485u, 800430746u, 235472647u, 607523346u, 463175808u, 3745374946u,
|
||||
3441880043u, 1315514151u, 2144187058u, 3936318837u, 303761673u, 496927619u, 1484008492u, 875436570u, 908925723u, 3702681198u,
|
||||
3035519578u, 1543217312u, 2767606354u, 1984772923u, 3076642518u, 2110698419u, 1383803177u, 3711886307u, 1584475951u, 328696964u,
|
||||
2801095507u, 3110654417u, 0u, 3240947181u, 1080041504u, 3810524412u, 2043195825u, 3069008731u, 3569248874u, 2370227147u,
|
||||
1742323390u, 1917532473u, 2497595978u, 2564049996u, 2968016984u, 2236272591u, 3144405200u, 3307925487u, 1340451498u, 3977706491u,
|
||||
2261074755u, 2597801293u, 1716859699u, 294946181u, 2328839493u, 3910203897u, 67502594u, 4269899647u, 2700103760u, 2017737788u,
|
||||
632987551u, 1273211048u, 2733855057u, 1576969123u, 2160083008u, 92966799u, 1068339858u, 566009245u, 1883781176u, 4043634165u,
|
||||
1675607228u, 2009183926u, 2943736538u, 1113792801u, 540020752u, 3843751935u, 4245615603u, 3211645650u, 2169294285u, 403966988u,
|
||||
641012499u, 3274697964u, 3202441055u, 899848087u, 2295088196u, 775493399u, 2472002756u, 1441965991u, 4236410494u, 2051489085u,
|
||||
3366741092u, 3135724893u, 841685273u, 3868554099u, 3231735904u, 429425025u, 2664517455u, 2743065820u, 1147544098u, 1417554474u,
|
||||
1001099408u, 193169544u, 2362066502u, 3341414126u, 1809037496u, 675025940u, 2809781982u, 3168951902u, 371002123u, 2910247899u,
|
||||
3678134496u, 1683370546u, 1951283770u, 337512970u, 2463844681u, 201983494u, 1215046692u, 3101973596u, 2673722050u, 3178157011u,
|
||||
1139780780u, 3299238498u, 967348625u, 832869781u, 3543655652u, 4069226873u, 3576883175u, 2336475336u, 1851340599u, 3669454189u,
|
||||
25988493u, 2976175573u, 2631028302u, 1239460265u, 3635702892u, 2902087254u, 4077384948u, 3475368682u, 3400492389u, 4102978170u,
|
||||
1206496942u, 270010376u, 1876277946u, 4035475576u, 1248797989u, 1550986798u, 941890588u, 1475454630u, 1942467764u, 2538718918u,
|
||||
3408128232u, 2709315037u, 3902567540u, 1042358047u, 2531085131u, 1641856445u, 226921355u, 260409994u, 3767562352u, 2084716094u,
|
||||
1908716981u, 3433719398u, 2430093384u, 100991747u, 4144101110u, 470945294u, 3265487201u, 1784624437u, 2935576407u, 1775286713u,
|
||||
395413126u, 2572730817u, 975641885u, 666476190u, 3644383713u, 3943954680u, 733190296u, 573772049u, 3535497577u, 2842745305u,
|
||||
126455438u, 866620564u, 766942107u, 1008868894u, 361924487u, 3374377449u, 2269761230u, 2868860245u, 1350051880u, 2776293343u,
|
||||
59739276u, 1509466529u, 159418761u, 437718285u, 1708834751u, 3610371814u, 2227585602u, 3501746280u, 2193834305u, 699439513u,
|
||||
1517759789u, 504434447u, 2076946608u, 2835108948u, 1842789307u, 742004246u
|
||||
};
|
||||
|
||||
private static readonly uint[] Tinv0 = new uint[256]
|
||||
{
|
||||
1353184337u, 1399144830u, 3282310938u, 2522752826u, 3412831035u, 4047871263u, 2874735276u, 2466505547u, 1442459680u, 4134368941u,
|
||||
2440481928u, 625738485u, 4242007375u, 3620416197u, 2151953702u, 2409849525u, 1230680542u, 1729870373u, 2551114309u, 3787521629u,
|
||||
41234371u, 317738113u, 2744600205u, 3338261355u, 3881799427u, 2510066197u, 3950669247u, 3663286933u, 763608788u, 3542185048u,
|
||||
694804553u, 1154009486u, 1787413109u, 2021232372u, 1799248025u, 3715217703u, 3058688446u, 397248752u, 1722556617u, 3023752829u,
|
||||
407560035u, 2184256229u, 1613975959u, 1165972322u, 3765920945u, 2226023355u, 480281086u, 2485848313u, 1483229296u, 436028815u,
|
||||
2272059028u, 3086515026u, 601060267u, 3791801202u, 1468997603u, 715871590u, 120122290u, 63092015u, 2591802758u, 2768779219u,
|
||||
4068943920u, 2997206819u, 3127509762u, 1552029421u, 723308426u, 2461301159u, 4042393587u, 2715969870u, 3455375973u, 3586000134u,
|
||||
526529745u, 2331944644u, 2639474228u, 2689987490u, 853641733u, 1978398372u, 971801355u, 2867814464u, 111112542u, 1360031421u,
|
||||
4186579262u, 1023860118u, 2919579357u, 1186850381u, 3045938321u, 90031217u, 1876166148u, 4279586912u, 620468249u, 2548678102u,
|
||||
3426959497u, 2006899047u, 3175278768u, 2290845959u, 945494503u, 3689859193u, 1191869601u, 3910091388u, 3374220536u, 0u,
|
||||
2206629897u, 1223502642u, 2893025566u, 1316117100u, 4227796733u, 1446544655u, 517320253u, 658058550u, 1691946762u, 564550760u,
|
||||
3511966619u, 976107044u, 2976320012u, 266819475u, 3533106868u, 2660342555u, 1338359936u, 2720062561u, 1766553434u, 370807324u,
|
||||
179999714u, 3844776128u, 1138762300u, 488053522u, 185403662u, 2915535858u, 3114841645u, 3366526484u, 2233069911u, 1275557295u,
|
||||
3151862254u, 4250959779u, 2670068215u, 3170202204u, 3309004356u, 880737115u, 1982415755u, 3703972811u, 1761406390u, 1676797112u,
|
||||
3403428311u, 277177154u, 1076008723u, 538035844u, 2099530373u, 4164795346u, 288553390u, 1839278535u, 1261411869u, 4080055004u,
|
||||
3964831245u, 3504587127u, 1813426987u, 2579067049u, 4199060497u, 577038663u, 3297574056u, 440397984u, 3626794326u, 4019204898u,
|
||||
3343796615u, 3251714265u, 4272081548u, 906744984u, 3481400742u, 685669029u, 646887386u, 2764025151u, 3835509292u, 227702864u,
|
||||
2613862250u, 1648787028u, 3256061430u, 3904428176u, 1593260334u, 4121936770u, 3196083615u, 2090061929u, 2838353263u, 3004310991u,
|
||||
999926984u, 2809993232u, 1852021992u, 2075868123u, 158869197u, 4095236462u, 28809964u, 2828685187u, 1701746150u, 2129067946u,
|
||||
147831841u, 3873969647u, 3650873274u, 3459673930u, 3557400554u, 3598495785u, 2947720241u, 824393514u, 815048134u, 3227951669u,
|
||||
935087732u, 2798289660u, 2966458592u, 366520115u, 1251476721u, 4158319681u, 240176511u, 804688151u, 2379631990u, 1303441219u,
|
||||
1414376140u, 3741619940u, 3820343710u, 461924940u, 3089050817u, 2136040774u, 82468509u, 1563790337u, 1937016826u, 776014843u,
|
||||
1511876531u, 1389550482u, 861278441u, 323475053u, 2355222426u, 2047648055u, 2383738969u, 2302415851u, 3995576782u, 902390199u,
|
||||
3991215329u, 1018251130u, 1507840668u, 1064563285u, 2043548696u, 3208103795u, 3939366739u, 1537932639u, 342834655u, 2262516856u,
|
||||
2180231114u, 1053059257u, 741614648u, 1598071746u, 1925389590u, 203809468u, 2336832552u, 1100287487u, 1895934009u, 3736275976u,
|
||||
2632234200u, 2428589668u, 1636092795u, 1890988757u, 1952214088u, 1113045200u
|
||||
};
|
||||
|
||||
private static readonly uint[] Tinv1 = new uint[256]
|
||||
{
|
||||
2817806672u, 1698790995u, 2752977603u, 1579629206u, 1806384075u, 1167925233u, 1492823211u, 65227667u, 4197458005u, 1836494326u,
|
||||
1993115793u, 1275262245u, 3622129660u, 3408578007u, 1144333952u, 2741155215u, 1521606217u, 465184103u, 250234264u, 3237895649u,
|
||||
1966064386u, 4031545618u, 2537983395u, 4191382470u, 1603208167u, 2626819477u, 2054012907u, 1498584538u, 2210321453u, 561273043u,
|
||||
1776306473u, 3368652356u, 2311222634u, 2039411832u, 1045993835u, 1907959773u, 1340194486u, 2911432727u, 2887829862u, 986611124u,
|
||||
1256153880u, 823846274u, 860985184u, 2136171077u, 2003087840u, 2926295940u, 2692873756u, 722008468u, 1749577816u, 4249194265u,
|
||||
1826526343u, 4168831671u, 3547573027u, 38499042u, 2401231703u, 2874500650u, 686535175u, 3266653955u, 2076542618u, 137876389u,
|
||||
2267558130u, 2780767154u, 1778582202u, 2182540636u, 483363371u, 3027871634u, 4060607472u, 3798552225u, 4107953613u, 3188000469u,
|
||||
1647628575u, 4272342154u, 1395537053u, 1442030240u, 3783918898u, 3958809717u, 3968011065u, 4016062634u, 2675006982u, 275692881u,
|
||||
2317434617u, 115185213u, 88006062u, 3185986886u, 2371129781u, 1573155077u, 3557164143u, 357589247u, 4221049124u, 3921532567u,
|
||||
1128303052u, 2665047927u, 1122545853u, 2341013384u, 1528424248u, 4006115803u, 175939911u, 256015593u, 512030921u, 0u,
|
||||
2256537987u, 3979031112u, 1880170156u, 1918528590u, 4279172603u, 948244310u, 3584965918u, 959264295u, 3641641572u, 2791073825u,
|
||||
1415289809u, 775300154u, 1728711857u, 3881276175u, 2532226258u, 2442861470u, 3317727311u, 551313826u, 1266113129u, 437394454u,
|
||||
3130253834u, 715178213u, 3760340035u, 387650077u, 218697227u, 3347837613u, 2830511545u, 2837320904u, 435246981u, 125153100u,
|
||||
3717852859u, 1618977789u, 637663135u, 4117912764u, 996558021u, 2130402100u, 692292470u, 3324234716u, 4243437160u, 4058298467u,
|
||||
3694254026u, 2237874704u, 580326208u, 298222624u, 608863613u, 1035719416u, 855223825u, 2703869805u, 798891339u, 817028339u,
|
||||
1384517100u, 3821107152u, 380840812u, 3111168409u, 1217663482u, 1693009698u, 2365368516u, 1072734234u, 746411736u, 2419270383u,
|
||||
1313441735u, 3510163905u, 2731183358u, 198481974u, 2180359887u, 3732579624u, 2394413606u, 3215802276u, 2637835492u, 2457358349u,
|
||||
3428805275u, 1182684258u, 328070850u, 3101200616u, 4147719774u, 2948825845u, 2153619390u, 2479909244u, 768962473u, 304467891u,
|
||||
2578237499u, 2098729127u, 1671227502u, 3141262203u, 2015808777u, 408514292u, 3080383489u, 2588902312u, 1855317605u, 3875515006u,
|
||||
3485212936u, 3893751782u, 2615655129u, 913263310u, 161475284u, 2091919830u, 2997105071u, 591342129u, 2493892144u, 1721906624u,
|
||||
3159258167u, 3397581990u, 3499155632u, 3634836245u, 2550460746u, 3672916471u, 1355644686u, 4136703791u, 3595400845u, 2968470349u,
|
||||
1303039060u, 76997855u, 3050413795u, 2288667675u, 523026872u, 1365591679u, 3932069124u, 898367837u, 1955068531u, 1091304238u,
|
||||
493335386u, 3537605202u, 1443948851u, 1205234963u, 1641519756u, 211892090u, 351820174u, 1007938441u, 665439982u, 3378624309u,
|
||||
3843875309u, 2974251580u, 3755121753u, 1945261375u, 3457423481u, 935818175u, 3455538154u, 2868731739u, 1866325780u, 3678697606u,
|
||||
4088384129u, 3295197502u, 874788908u, 1084473951u, 3273463410u, 635616268u, 1228679307u, 2500722497u, 27801969u, 3003910366u,
|
||||
3837057180u, 3243664528u, 2227927905u, 3056784752u, 1550600308u, 1471729730u
|
||||
};
|
||||
|
||||
private static readonly uint[] Tinv2 = new uint[256]
|
||||
{
|
||||
4098969767u, 1098797925u, 387629988u, 658151006u, 2872822635u, 2636116293u, 4205620056u, 3813380867u, 807425530u, 1991112301u,
|
||||
3431502198u, 49620300u, 3847224535u, 717608907u, 891715652u, 1656065955u, 2984135002u, 3123013403u, 3930429454u, 4267565504u,
|
||||
801309301u, 1283527408u, 1183687575u, 3547055865u, 2399397727u, 2450888092u, 1841294202u, 1385552473u, 3201576323u, 1951978273u,
|
||||
3762891113u, 3381544136u, 3262474889u, 2398386297u, 1486449470u, 3106397553u, 3787372111u, 2297436077u, 550069932u, 3464344634u,
|
||||
3747813450u, 451248689u, 1368875059u, 1398949247u, 1689378935u, 1807451310u, 2180914336u, 150574123u, 1215322216u, 1167006205u,
|
||||
3734275948u, 2069018616u, 1940595667u, 1265820162u, 534992783u, 1432758955u, 3954313000u, 3039757250u, 3313932923u, 936617224u,
|
||||
674296455u, 3206787749u, 50510442u, 384654466u, 3481938716u, 2041025204u, 133427442u, 1766760930u, 3664104948u, 84334014u,
|
||||
886120290u, 2797898494u, 775200083u, 4087521365u, 2315596513u, 4137973227u, 2198551020u, 1614850799u, 1901987487u, 1857900816u,
|
||||
557775242u, 3717610758u, 1054715397u, 3863824061u, 1418835341u, 3295741277u, 100954068u, 1348534037u, 2551784699u, 3184957417u,
|
||||
1082772547u, 3647436702u, 3903896898u, 2298972299u, 434583643u, 3363429358u, 2090944266u, 1115482383u, 2230896926u, 0u,
|
||||
2148107142u, 724715757u, 287222896u, 1517047410u, 251526143u, 2232374840u, 2923241173u, 758523705u, 252339417u, 1550328230u,
|
||||
1536938324u, 908343854u, 168604007u, 1469255655u, 4004827798u, 2602278545u, 3229634501u, 3697386016u, 2002413899u, 303830554u,
|
||||
2481064634u, 2696996138u, 574374880u, 454171927u, 151915277u, 2347937223u, 3056449960u, 504678569u, 4049044761u, 1974422535u,
|
||||
2582559709u, 2141453664u, 33005350u, 1918680309u, 1715782971u, 4217058430u, 1133213225u, 600562886u, 3988154620u, 3837289457u,
|
||||
836225756u, 1665273989u, 2534621218u, 3330547729u, 1250262308u, 3151165501u, 4188934450u, 700935585u, 2652719919u, 3000824624u,
|
||||
2249059410u, 3245854947u, 3005967382u, 1890163129u, 2484206152u, 3913753188u, 4238918796u, 4037024319u, 2102843436u, 857927568u,
|
||||
1233635150u, 953795025u, 3398237858u, 3566745099u, 4121350017u, 2057644254u, 3084527246u, 2906629311u, 976020637u, 2018512274u,
|
||||
1600822220u, 2119459398u, 2381758995u, 3633375416u, 959340279u, 3280139695u, 1570750080u, 3496574099u, 3580864813u, 634368786u,
|
||||
2898803609u, 403744637u, 2632478307u, 1004239803u, 650971512u, 1500443672u, 2599158199u, 1334028442u, 2514904430u, 4289363686u,
|
||||
3156281551u, 368043752u, 3887782299u, 1867173430u, 2682967049u, 2955531900u, 2754719666u, 1059729699u, 2781229204u, 2721431654u,
|
||||
1316239292u, 2197595850u, 2430644432u, 2805143000u, 82922136u, 3963746266u, 3447656016u, 2434215926u, 1299615190u, 4014165424u,
|
||||
2865517645u, 2531581700u, 3516851125u, 1783372680u, 750893087u, 1699118929u, 1587348714u, 2348899637u, 2281337716u, 201010753u,
|
||||
1739807261u, 3683799762u, 283718486u, 3597472583u, 3617229921u, 2704767500u, 4166618644u, 334203196u, 2848910887u, 1639396809u,
|
||||
484568549u, 1199193265u, 3533461983u, 4065673075u, 337148366u, 3346251575u, 4149471949u, 4250885034u, 1038029935u, 1148749531u,
|
||||
2949284339u, 1756970692u, 607661108u, 2747424576u, 488010435u, 3803974693u, 1009290057u, 234832277u, 2822336769u, 201907891u,
|
||||
3034094820u, 1449431233u, 3413860740u, 852848822u, 1816687708u, 3100656215u
|
||||
};
|
||||
|
||||
private static readonly uint[] Tinv3 = new uint[256]
|
||||
{
|
||||
1364240372u, 2119394625u, 449029143u, 982933031u, 1003187115u, 535905693u, 2896910586u, 1267925987u, 542505520u, 2918608246u,
|
||||
2291234508u, 4112862210u, 1341970405u, 3319253802u, 645940277u, 3046089570u, 3729349297u, 627514298u, 1167593194u, 1575076094u,
|
||||
3271718191u, 2165502028u, 2376308550u, 1808202195u, 65494927u, 362126482u, 3219880557u, 2514114898u, 3559752638u, 1490231668u,
|
||||
1227450848u, 2386872521u, 1969916354u, 4101536142u, 2573942360u, 668823993u, 3199619041u, 4028083592u, 3378949152u, 2108963534u,
|
||||
1662536415u, 3850514714u, 2539664209u, 1648721747u, 2984277860u, 3146034795u, 4263288961u, 4187237128u, 1884842056u, 2400845125u,
|
||||
2491903198u, 1387788411u, 2871251827u, 1927414347u, 3814166303u, 1714072405u, 2986813675u, 788775605u, 2258271173u, 3550808119u,
|
||||
821200680u, 598910399u, 45771267u, 3982262806u, 2318081231u, 2811409529u, 4092654087u, 1319232105u, 1707996378u, 114671109u,
|
||||
3508494900u, 3297443494u, 882725678u, 2728416755u, 87220618u, 2759191542u, 188345475u, 1084944224u, 1577492337u, 3176206446u,
|
||||
1056541217u, 2520581853u, 3719169342u, 1296481766u, 2444594516u, 1896177092u, 74437638u, 1627329872u, 421854104u, 3600279997u,
|
||||
2311865152u, 1735892697u, 2965193448u, 126389129u, 3879230233u, 2044456648u, 2705787516u, 2095648578u, 4173930116u, 0u,
|
||||
159614592u, 843640107u, 514617361u, 1817080410u, 4261150478u, 257308805u, 1025430958u, 908540205u, 174381327u, 1747035740u,
|
||||
2614187099u, 607792694u, 212952842u, 2467293015u, 3033700078u, 463376795u, 2152711616u, 1638015196u, 1516850039u, 471210514u,
|
||||
3792353939u, 3236244128u, 1011081250u, 303896347u, 235605257u, 4071475083u, 767142070u, 348694814u, 1468340721u, 2940995445u,
|
||||
4005289369u, 2751291519u, 4154402305u, 1555887474u, 1153776486u, 1530167035u, 2339776835u, 3420243491u, 3060333805u, 3093557732u,
|
||||
3620396081u, 1108378979u, 322970263u, 2216694214u, 2239571018u, 3539484091u, 2920362745u, 3345850665u, 491466654u, 3706925234u,
|
||||
233591430u, 2010178497u, 728503987u, 2845423984u, 301615252u, 1193436393u, 2831453436u, 2686074864u, 1457007741u, 586125363u,
|
||||
2277985865u, 3653357880u, 2365498058u, 2553678804u, 2798617077u, 2770919034u, 3659959991u, 1067761581u, 753179962u, 1343066744u,
|
||||
1788595295u, 1415726718u, 4139914125u, 2431170776u, 777975609u, 2197139395u, 2680062045u, 1769771984u, 1873358293u, 3484619301u,
|
||||
3359349164u, 279411992u, 3899548572u, 3682319163u, 3439949862u, 1861490777u, 3959535514u, 2208864847u, 3865407125u, 2860443391u,
|
||||
554225596u, 4024887317u, 3134823399u, 1255028335u, 3939764639u, 701922480u, 833598116u, 707863359u, 3325072549u, 901801634u,
|
||||
1949809742u, 4238789250u, 3769684112u, 857069735u, 4048197636u, 1106762476u, 2131644621u, 389019281u, 1989006925u, 1129165039u,
|
||||
3428076970u, 3839820950u, 2665723345u, 1276872810u, 3250069292u, 1182749029u, 2634345054u, 22885772u, 4201870471u, 4214112523u,
|
||||
3009027431u, 2454901467u, 3912455696u, 1829980118u, 2592891351u, 930745505u, 1502483704u, 3951639571u, 3471714217u, 3073755489u,
|
||||
3790464284u, 2050797895u, 2623135698u, 1430221810u, 410635796u, 1941911495u, 1407897079u, 1599843069u, 3742658365u, 2022103876u,
|
||||
3397514159u, 3107898472u, 942421028u, 3261022371u, 376619805u, 3154912738u, 680216892u, 4282488077u, 963707304u, 148812556u,
|
||||
3634160820u, 1687208278u, 2069988555u, 3580933682u, 1215585388u, 3494008760u
|
||||
};
|
||||
|
||||
private int ROUNDS;
|
||||
|
||||
private uint[][] WorkingKey;
|
||||
|
||||
private uint C0;
|
||||
|
||||
private uint C1;
|
||||
|
||||
private uint C2;
|
||||
|
||||
private uint C3;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
public virtual string AlgorithmName => "AES";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
private static uint Shift(uint r, int shift)
|
||||
{
|
||||
return (r >> shift) | (r << 32 - shift);
|
||||
}
|
||||
|
||||
private static uint FFmulX(uint x)
|
||||
{
|
||||
return ((x & 0x7F7F7F7F) << 1) ^ (((x & 0x80808080u) >> 7) * 27);
|
||||
}
|
||||
|
||||
private static uint FFmulX2(uint x)
|
||||
{
|
||||
uint num = (x & 0x3F3F3F3F) << 2;
|
||||
uint num2 = x & 0xC0C0C0C0u;
|
||||
num2 ^= num2 >> 1;
|
||||
return num ^ (num2 >> 2) ^ (num2 >> 5);
|
||||
}
|
||||
|
||||
private static uint Inv_Mcol(uint x)
|
||||
{
|
||||
uint num = x;
|
||||
uint num2 = num ^ Shift(num, 8);
|
||||
num ^= FFmulX(num2);
|
||||
num2 ^= FFmulX2(num);
|
||||
return num ^ (num2 ^ Shift(num2, 16));
|
||||
}
|
||||
|
||||
private static uint SubWord(uint x)
|
||||
{
|
||||
return (uint)(S[x & 0xFF] | (S[(x >> 8) & 0xFF] << 8) | (S[(x >> 16) & 0xFF] << 16) | (S[(x >> 24) & 0xFF] << 24));
|
||||
}
|
||||
|
||||
private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption)
|
||||
{
|
||||
int num = key.Length;
|
||||
if (num < 16 || num > 32 || (num & 7) != 0)
|
||||
{
|
||||
throw new ArgumentException("Key length not 128/192/256 bits.");
|
||||
}
|
||||
int num2 = num >> 2;
|
||||
ROUNDS = num2 + 6;
|
||||
uint[][] array = new uint[ROUNDS + 1][];
|
||||
for (int i = 0; i <= ROUNDS; i++)
|
||||
{
|
||||
array[i] = new uint[4];
|
||||
}
|
||||
switch (num2)
|
||||
{
|
||||
case 4:
|
||||
{
|
||||
uint num21 = Pack.LE_To_UInt32(key, 0);
|
||||
array[0][0] = num21;
|
||||
uint num22 = Pack.LE_To_UInt32(key, 4);
|
||||
array[0][1] = num22;
|
||||
uint num23 = Pack.LE_To_UInt32(key, 8);
|
||||
array[0][2] = num23;
|
||||
uint num24 = Pack.LE_To_UInt32(key, 12);
|
||||
array[0][3] = num24;
|
||||
for (int l = 1; l <= 10; l++)
|
||||
{
|
||||
uint num25 = SubWord(Shift(num24, 8)) ^ rcon[l - 1];
|
||||
num21 ^= num25;
|
||||
array[l][0] = num21;
|
||||
num22 ^= num21;
|
||||
array[l][1] = num22;
|
||||
num23 ^= num22;
|
||||
array[l][2] = num23;
|
||||
num24 ^= num23;
|
||||
array[l][3] = num24;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
uint num13 = Pack.LE_To_UInt32(key, 0);
|
||||
array[0][0] = num13;
|
||||
uint num14 = Pack.LE_To_UInt32(key, 4);
|
||||
array[0][1] = num14;
|
||||
uint num15 = Pack.LE_To_UInt32(key, 8);
|
||||
array[0][2] = num15;
|
||||
uint num16 = Pack.LE_To_UInt32(key, 12);
|
||||
array[0][3] = num16;
|
||||
uint num17 = Pack.LE_To_UInt32(key, 16);
|
||||
array[1][0] = num17;
|
||||
uint num18 = Pack.LE_To_UInt32(key, 20);
|
||||
array[1][1] = num18;
|
||||
uint num19 = 1u;
|
||||
uint num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num19 <<= 1;
|
||||
num13 ^= num20;
|
||||
array[1][2] = num13;
|
||||
num14 ^= num13;
|
||||
array[1][3] = num14;
|
||||
num15 ^= num14;
|
||||
array[2][0] = num15;
|
||||
num16 ^= num15;
|
||||
array[2][1] = num16;
|
||||
num17 ^= num16;
|
||||
array[2][2] = num17;
|
||||
num18 ^= num17;
|
||||
array[2][3] = num18;
|
||||
for (int k = 3; k < 12; k += 3)
|
||||
{
|
||||
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num19 <<= 1;
|
||||
num13 ^= num20;
|
||||
array[k][0] = num13;
|
||||
num14 ^= num13;
|
||||
array[k][1] = num14;
|
||||
num15 ^= num14;
|
||||
array[k][2] = num15;
|
||||
num16 ^= num15;
|
||||
array[k][3] = num16;
|
||||
num17 ^= num16;
|
||||
array[k + 1][0] = num17;
|
||||
num18 ^= num17;
|
||||
array[k + 1][1] = num18;
|
||||
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num19 <<= 1;
|
||||
num13 ^= num20;
|
||||
array[k + 1][2] = num13;
|
||||
num14 ^= num13;
|
||||
array[k + 1][3] = num14;
|
||||
num15 ^= num14;
|
||||
array[k + 2][0] = num15;
|
||||
num16 ^= num15;
|
||||
array[k + 2][1] = num16;
|
||||
num17 ^= num16;
|
||||
array[k + 2][2] = num17;
|
||||
num18 ^= num17;
|
||||
array[k + 2][3] = num18;
|
||||
}
|
||||
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num13 ^= num20;
|
||||
array[12][0] = num13;
|
||||
num14 ^= num13;
|
||||
array[12][1] = num14;
|
||||
num15 ^= num14;
|
||||
array[12][2] = num15;
|
||||
num16 ^= num15;
|
||||
array[12][3] = num16;
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
uint num3 = Pack.LE_To_UInt32(key, 0);
|
||||
array[0][0] = num3;
|
||||
uint num4 = Pack.LE_To_UInt32(key, 4);
|
||||
array[0][1] = num4;
|
||||
uint num5 = Pack.LE_To_UInt32(key, 8);
|
||||
array[0][2] = num5;
|
||||
uint num6 = Pack.LE_To_UInt32(key, 12);
|
||||
array[0][3] = num6;
|
||||
uint num7 = Pack.LE_To_UInt32(key, 16);
|
||||
array[1][0] = num7;
|
||||
uint num8 = Pack.LE_To_UInt32(key, 20);
|
||||
array[1][1] = num8;
|
||||
uint num9 = Pack.LE_To_UInt32(key, 24);
|
||||
array[1][2] = num9;
|
||||
uint num10 = Pack.LE_To_UInt32(key, 28);
|
||||
array[1][3] = num10;
|
||||
uint num11 = 1u;
|
||||
uint num12;
|
||||
for (int j = 2; j < 14; j += 2)
|
||||
{
|
||||
num12 = SubWord(Shift(num10, 8)) ^ num11;
|
||||
num11 <<= 1;
|
||||
num3 ^= num12;
|
||||
array[j][0] = num3;
|
||||
num4 ^= num3;
|
||||
array[j][1] = num4;
|
||||
num5 ^= num4;
|
||||
array[j][2] = num5;
|
||||
num6 ^= num5;
|
||||
array[j][3] = num6;
|
||||
num12 = SubWord(num6);
|
||||
num7 ^= num12;
|
||||
array[j + 1][0] = num7;
|
||||
num8 ^= num7;
|
||||
array[j + 1][1] = num8;
|
||||
num9 ^= num8;
|
||||
array[j + 1][2] = num9;
|
||||
num10 ^= num9;
|
||||
array[j + 1][3] = num10;
|
||||
}
|
||||
num12 = SubWord(Shift(num10, 8)) ^ num11;
|
||||
num3 ^= num12;
|
||||
array[14][0] = num3;
|
||||
num4 ^= num3;
|
||||
array[14][1] = num4;
|
||||
num5 ^= num4;
|
||||
array[14][2] = num5;
|
||||
num6 ^= num5;
|
||||
array[14][3] = num6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException("Should never get here");
|
||||
}
|
||||
if (!forEncryption)
|
||||
{
|
||||
for (int m = 1; m < ROUNDS; m++)
|
||||
{
|
||||
uint[] array2 = array[m];
|
||||
for (int n = 0; n < 4; n++)
|
||||
{
|
||||
array2[n] = Inv_Mcol(array2[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter keyParameter))
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to AES init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption);
|
||||
this.forEncryption = forEncryption;
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (WorkingKey == null)
|
||||
{
|
||||
throw new InvalidOperationException("AES engine not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 16, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 16, "output buffer too short");
|
||||
UnPackBlock(input, inOff);
|
||||
if (forEncryption)
|
||||
{
|
||||
EncryptBlock(WorkingKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
DecryptBlock(WorkingKey);
|
||||
}
|
||||
PackBlock(output, outOff);
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
private void UnPackBlock(byte[] bytes, int off)
|
||||
{
|
||||
C0 = Pack.LE_To_UInt32(bytes, off);
|
||||
C1 = Pack.LE_To_UInt32(bytes, off + 4);
|
||||
C2 = Pack.LE_To_UInt32(bytes, off + 8);
|
||||
C3 = Pack.LE_To_UInt32(bytes, off + 12);
|
||||
}
|
||||
|
||||
private void PackBlock(byte[] bytes, int off)
|
||||
{
|
||||
Pack.UInt32_To_LE(C0, bytes, off);
|
||||
Pack.UInt32_To_LE(C1, bytes, off + 4);
|
||||
Pack.UInt32_To_LE(C2, bytes, off + 8);
|
||||
Pack.UInt32_To_LE(C3, bytes, off + 12);
|
||||
}
|
||||
|
||||
private void EncryptBlock(uint[][] KW)
|
||||
{
|
||||
uint[] array = KW[0];
|
||||
uint num = C0 ^ array[0];
|
||||
uint num2 = C1 ^ array[1];
|
||||
uint num3 = C2 ^ array[2];
|
||||
uint num4 = C3 ^ array[3];
|
||||
int num5 = 1;
|
||||
uint num6;
|
||||
uint num7;
|
||||
uint num8;
|
||||
while (num5 < ROUNDS - 1)
|
||||
{
|
||||
array = KW[num5++];
|
||||
num6 = T0[num & 0xFF] ^ T1[(num2 >> 8) & 0xFF] ^ T2[(num3 >> 16) & 0xFF] ^ T3[num4 >> 24] ^ array[0];
|
||||
num7 = T0[num2 & 0xFF] ^ T1[(num3 >> 8) & 0xFF] ^ T2[(num4 >> 16) & 0xFF] ^ T3[num >> 24] ^ array[1];
|
||||
num8 = T0[num3 & 0xFF] ^ T1[(num4 >> 8) & 0xFF] ^ T2[(num >> 16) & 0xFF] ^ T3[num2 >> 24] ^ array[2];
|
||||
num4 = T0[num4 & 0xFF] ^ T1[(num >> 8) & 0xFF] ^ T2[(num2 >> 16) & 0xFF] ^ T3[num3 >> 24] ^ array[3];
|
||||
array = KW[num5++];
|
||||
num = T0[num6 & 0xFF] ^ T1[(num7 >> 8) & 0xFF] ^ T2[(num8 >> 16) & 0xFF] ^ T3[num4 >> 24] ^ array[0];
|
||||
num2 = T0[num7 & 0xFF] ^ T1[(num8 >> 8) & 0xFF] ^ T2[(num4 >> 16) & 0xFF] ^ T3[num6 >> 24] ^ array[1];
|
||||
num3 = T0[num8 & 0xFF] ^ T1[(num4 >> 8) & 0xFF] ^ T2[(num6 >> 16) & 0xFF] ^ T3[num7 >> 24] ^ array[2];
|
||||
num4 = T0[num4 & 0xFF] ^ T1[(num6 >> 8) & 0xFF] ^ T2[(num7 >> 16) & 0xFF] ^ T3[num8 >> 24] ^ array[3];
|
||||
}
|
||||
array = KW[num5++];
|
||||
num6 = T0[num & 0xFF] ^ T1[(num2 >> 8) & 0xFF] ^ T2[(num3 >> 16) & 0xFF] ^ T3[num4 >> 24] ^ array[0];
|
||||
num7 = T0[num2 & 0xFF] ^ T1[(num3 >> 8) & 0xFF] ^ T2[(num4 >> 16) & 0xFF] ^ T3[num >> 24] ^ array[1];
|
||||
num8 = T0[num3 & 0xFF] ^ T1[(num4 >> 8) & 0xFF] ^ T2[(num >> 16) & 0xFF] ^ T3[num2 >> 24] ^ array[2];
|
||||
num4 = T0[num4 & 0xFF] ^ T1[(num >> 8) & 0xFF] ^ T2[(num2 >> 16) & 0xFF] ^ T3[num3 >> 24] ^ array[3];
|
||||
array = KW[num5];
|
||||
C0 = (uint)(S[num6 & 0xFF] ^ (S[(num7 >> 8) & 0xFF] << 8) ^ (S[(num8 >> 16) & 0xFF] << 16) ^ (S[num4 >> 24] << 24)) ^ array[0];
|
||||
C1 = (uint)(S[num7 & 0xFF] ^ (S[(num8 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (S[num6 >> 24] << 24)) ^ array[1];
|
||||
C2 = (uint)(S[num8 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num6 >> 16) & 0xFF] << 16) ^ (S[num7 >> 24] << 24)) ^ array[2];
|
||||
C3 = (uint)(S[num4 & 0xFF] ^ (S[(num6 >> 8) & 0xFF] << 8) ^ (S[(num7 >> 16) & 0xFF] << 16) ^ (S[num8 >> 24] << 24)) ^ array[3];
|
||||
}
|
||||
|
||||
private void DecryptBlock(uint[][] KW)
|
||||
{
|
||||
uint[] array = KW[ROUNDS];
|
||||
uint num = C0 ^ array[0];
|
||||
uint num2 = C1 ^ array[1];
|
||||
uint num3 = C2 ^ array[2];
|
||||
uint num4 = C3 ^ array[3];
|
||||
int num5 = ROUNDS - 1;
|
||||
uint num6;
|
||||
uint num7;
|
||||
uint num8;
|
||||
while (num5 > 1)
|
||||
{
|
||||
array = KW[num5--];
|
||||
num6 = Tinv0[num & 0xFF] ^ Tinv1[(num4 >> 8) & 0xFF] ^ Tinv2[(num3 >> 16) & 0xFF] ^ Tinv3[num2 >> 24] ^ array[0];
|
||||
num7 = Tinv0[num2 & 0xFF] ^ Tinv1[(num >> 8) & 0xFF] ^ Tinv2[(num4 >> 16) & 0xFF] ^ Tinv3[num3 >> 24] ^ array[1];
|
||||
num8 = Tinv0[num3 & 0xFF] ^ Tinv1[(num2 >> 8) & 0xFF] ^ Tinv2[(num >> 16) & 0xFF] ^ Tinv3[num4 >> 24] ^ array[2];
|
||||
num4 = Tinv0[num4 & 0xFF] ^ Tinv1[(num3 >> 8) & 0xFF] ^ Tinv2[(num2 >> 16) & 0xFF] ^ Tinv3[num >> 24] ^ array[3];
|
||||
array = KW[num5--];
|
||||
num = Tinv0[num6 & 0xFF] ^ Tinv1[(num4 >> 8) & 0xFF] ^ Tinv2[(num8 >> 16) & 0xFF] ^ Tinv3[num7 >> 24] ^ array[0];
|
||||
num2 = Tinv0[num7 & 0xFF] ^ Tinv1[(num6 >> 8) & 0xFF] ^ Tinv2[(num4 >> 16) & 0xFF] ^ Tinv3[num8 >> 24] ^ array[1];
|
||||
num3 = Tinv0[num8 & 0xFF] ^ Tinv1[(num7 >> 8) & 0xFF] ^ Tinv2[(num6 >> 16) & 0xFF] ^ Tinv3[num4 >> 24] ^ array[2];
|
||||
num4 = Tinv0[num4 & 0xFF] ^ Tinv1[(num8 >> 8) & 0xFF] ^ Tinv2[(num7 >> 16) & 0xFF] ^ Tinv3[num6 >> 24] ^ array[3];
|
||||
}
|
||||
array = KW[1];
|
||||
num6 = Tinv0[num & 0xFF] ^ Tinv1[(num4 >> 8) & 0xFF] ^ Tinv2[(num3 >> 16) & 0xFF] ^ Tinv3[num2 >> 24] ^ array[0];
|
||||
num7 = Tinv0[num2 & 0xFF] ^ Tinv1[(num >> 8) & 0xFF] ^ Tinv2[(num4 >> 16) & 0xFF] ^ Tinv3[num3 >> 24] ^ array[1];
|
||||
num8 = Tinv0[num3 & 0xFF] ^ Tinv1[(num2 >> 8) & 0xFF] ^ Tinv2[(num >> 16) & 0xFF] ^ Tinv3[num4 >> 24] ^ array[2];
|
||||
num4 = Tinv0[num4 & 0xFF] ^ Tinv1[(num3 >> 8) & 0xFF] ^ Tinv2[(num2 >> 16) & 0xFF] ^ Tinv3[num >> 24] ^ array[3];
|
||||
array = KW[0];
|
||||
C0 = (uint)(Si[num6 & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num8 >> 16) & 0xFF] << 16) ^ (Si[num7 >> 24] << 24)) ^ array[0];
|
||||
C1 = (uint)(Si[num7 & 0xFF] ^ (Si[(num6 >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[num8 >> 24] << 24)) ^ array[1];
|
||||
C2 = (uint)(Si[num8 & 0xFF] ^ (Si[(num7 >> 8) & 0xFF] << 8) ^ (Si[(num6 >> 16) & 0xFF] << 16) ^ (Si[num4 >> 24] << 24)) ^ array[2];
|
||||
C3 = (uint)(Si[num4 & 0xFF] ^ (Si[(num8 >> 8) & 0xFF] << 8) ^ (Si[(num7 >> 16) & 0xFF] << 16) ^ (Si[num6 >> 24] << 24)) ^ array[3];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,454 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class AesLightEngine : IBlockCipher
|
||||
{
|
||||
private const uint m1 = 2155905152u;
|
||||
|
||||
private const uint m2 = 2139062143u;
|
||||
|
||||
private const uint m3 = 27u;
|
||||
|
||||
private const uint m4 = 3233857728u;
|
||||
|
||||
private const uint m5 = 1061109567u;
|
||||
|
||||
private const int BLOCK_SIZE = 16;
|
||||
|
||||
private static readonly byte[] S = new byte[256]
|
||||
{
|
||||
99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
|
||||
103, 43, 254, 215, 171, 118, 202, 130, 201, 125,
|
||||
250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
|
||||
114, 192, 183, 253, 147, 38, 54, 63, 247, 204,
|
||||
52, 165, 229, 241, 113, 216, 49, 21, 4, 199,
|
||||
35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
|
||||
235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
|
||||
90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
|
||||
83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
|
||||
190, 57, 74, 76, 88, 207, 208, 239, 170, 251,
|
||||
67, 77, 51, 133, 69, 249, 2, 127, 80, 60,
|
||||
159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
|
||||
188, 182, 218, 33, 16, 255, 243, 210, 205, 12,
|
||||
19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
|
||||
100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
|
||||
144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
|
||||
224, 50, 58, 10, 73, 6, 36, 92, 194, 211,
|
||||
172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
|
||||
141, 213, 78, 169, 108, 86, 244, 234, 101, 122,
|
||||
174, 8, 186, 120, 37, 46, 28, 166, 180, 198,
|
||||
232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
|
||||
181, 102, 72, 3, 246, 14, 97, 53, 87, 185,
|
||||
134, 193, 29, 158, 225, 248, 152, 17, 105, 217,
|
||||
142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
|
||||
140, 161, 137, 13, 191, 230, 66, 104, 65, 153,
|
||||
45, 15, 176, 84, 187, 22
|
||||
};
|
||||
|
||||
private static readonly byte[] Si = new byte[256]
|
||||
{
|
||||
82, 9, 106, 213, 48, 54, 165, 56, 191, 64,
|
||||
163, 158, 129, 243, 215, 251, 124, 227, 57, 130,
|
||||
155, 47, 255, 135, 52, 142, 67, 68, 196, 222,
|
||||
233, 203, 84, 123, 148, 50, 166, 194, 35, 61,
|
||||
238, 76, 149, 11, 66, 250, 195, 78, 8, 46,
|
||||
161, 102, 40, 217, 36, 178, 118, 91, 162, 73,
|
||||
109, 139, 209, 37, 114, 248, 246, 100, 134, 104,
|
||||
152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
|
||||
108, 112, 72, 80, 253, 237, 185, 218, 94, 21,
|
||||
70, 87, 167, 141, 157, 132, 144, 216, 171, 0,
|
||||
140, 188, 211, 10, 247, 228, 88, 5, 184, 179,
|
||||
69, 6, 208, 44, 30, 143, 202, 63, 15, 2,
|
||||
193, 175, 189, 3, 1, 19, 138, 107, 58, 145,
|
||||
17, 65, 79, 103, 220, 234, 151, 242, 207, 206,
|
||||
240, 180, 230, 115, 150, 172, 116, 34, 231, 173,
|
||||
53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
|
||||
71, 241, 26, 113, 29, 41, 197, 137, 111, 183,
|
||||
98, 14, 170, 24, 190, 27, 252, 86, 62, 75,
|
||||
198, 210, 121, 32, 154, 219, 192, 254, 120, 205,
|
||||
90, 244, 31, 221, 168, 51, 136, 7, 199, 49,
|
||||
177, 18, 16, 89, 39, 128, 236, 95, 96, 81,
|
||||
127, 169, 25, 181, 74, 13, 45, 229, 122, 159,
|
||||
147, 201, 156, 239, 160, 224, 59, 77, 174, 42,
|
||||
245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
|
||||
23, 43, 4, 126, 186, 119, 214, 38, 225, 105,
|
||||
20, 99, 85, 33, 12, 125
|
||||
};
|
||||
|
||||
private static readonly byte[] rcon = new byte[30]
|
||||
{
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 27, 54,
|
||||
108, 216, 171, 77, 154, 47, 94, 188, 99, 198,
|
||||
151, 53, 106, 212, 179, 125, 250, 239, 197, 145
|
||||
};
|
||||
|
||||
private int ROUNDS;
|
||||
|
||||
private uint[][] WorkingKey;
|
||||
|
||||
private uint C0;
|
||||
|
||||
private uint C1;
|
||||
|
||||
private uint C2;
|
||||
|
||||
private uint C3;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
public virtual string AlgorithmName => "AES";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
private static uint Shift(uint r, int shift)
|
||||
{
|
||||
return (r >> shift) | (r << 32 - shift);
|
||||
}
|
||||
|
||||
private static uint FFmulX(uint x)
|
||||
{
|
||||
return ((x & 0x7F7F7F7F) << 1) ^ (((x & 0x80808080u) >> 7) * 27);
|
||||
}
|
||||
|
||||
private static uint FFmulX2(uint x)
|
||||
{
|
||||
uint num = (x & 0x3F3F3F3F) << 2;
|
||||
uint num2 = x & 0xC0C0C0C0u;
|
||||
num2 ^= num2 >> 1;
|
||||
return num ^ (num2 >> 2) ^ (num2 >> 5);
|
||||
}
|
||||
|
||||
private static uint Mcol(uint x)
|
||||
{
|
||||
uint num = Shift(x, 8);
|
||||
uint num2 = x ^ num;
|
||||
return Shift(num2, 16) ^ num ^ FFmulX(num2);
|
||||
}
|
||||
|
||||
private static uint Inv_Mcol(uint x)
|
||||
{
|
||||
uint num = x;
|
||||
uint num2 = num ^ Shift(num, 8);
|
||||
num ^= FFmulX(num2);
|
||||
num2 ^= FFmulX2(num);
|
||||
return num ^ (num2 ^ Shift(num2, 16));
|
||||
}
|
||||
|
||||
private static uint SubWord(uint x)
|
||||
{
|
||||
return (uint)(S[x & 0xFF] | (S[(x >> 8) & 0xFF] << 8) | (S[(x >> 16) & 0xFF] << 16) | (S[(x >> 24) & 0xFF] << 24));
|
||||
}
|
||||
|
||||
private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption)
|
||||
{
|
||||
int num = key.Length;
|
||||
if (num < 16 || num > 32 || (num & 7) != 0)
|
||||
{
|
||||
throw new ArgumentException("Key length not 128/192/256 bits.");
|
||||
}
|
||||
int num2 = num >> 2;
|
||||
ROUNDS = num2 + 6;
|
||||
uint[][] array = new uint[ROUNDS + 1][];
|
||||
for (int i = 0; i <= ROUNDS; i++)
|
||||
{
|
||||
array[i] = new uint[4];
|
||||
}
|
||||
switch (num2)
|
||||
{
|
||||
case 4:
|
||||
{
|
||||
uint num21 = Pack.LE_To_UInt32(key, 0);
|
||||
array[0][0] = num21;
|
||||
uint num22 = Pack.LE_To_UInt32(key, 4);
|
||||
array[0][1] = num22;
|
||||
uint num23 = Pack.LE_To_UInt32(key, 8);
|
||||
array[0][2] = num23;
|
||||
uint num24 = Pack.LE_To_UInt32(key, 12);
|
||||
array[0][3] = num24;
|
||||
for (int l = 1; l <= 10; l++)
|
||||
{
|
||||
uint num25 = SubWord(Shift(num24, 8)) ^ rcon[l - 1];
|
||||
num21 ^= num25;
|
||||
array[l][0] = num21;
|
||||
num22 ^= num21;
|
||||
array[l][1] = num22;
|
||||
num23 ^= num22;
|
||||
array[l][2] = num23;
|
||||
num24 ^= num23;
|
||||
array[l][3] = num24;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
uint num13 = Pack.LE_To_UInt32(key, 0);
|
||||
array[0][0] = num13;
|
||||
uint num14 = Pack.LE_To_UInt32(key, 4);
|
||||
array[0][1] = num14;
|
||||
uint num15 = Pack.LE_To_UInt32(key, 8);
|
||||
array[0][2] = num15;
|
||||
uint num16 = Pack.LE_To_UInt32(key, 12);
|
||||
array[0][3] = num16;
|
||||
uint num17 = Pack.LE_To_UInt32(key, 16);
|
||||
array[1][0] = num17;
|
||||
uint num18 = Pack.LE_To_UInt32(key, 20);
|
||||
array[1][1] = num18;
|
||||
uint num19 = 1u;
|
||||
uint num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num19 <<= 1;
|
||||
num13 ^= num20;
|
||||
array[1][2] = num13;
|
||||
num14 ^= num13;
|
||||
array[1][3] = num14;
|
||||
num15 ^= num14;
|
||||
array[2][0] = num15;
|
||||
num16 ^= num15;
|
||||
array[2][1] = num16;
|
||||
num17 ^= num16;
|
||||
array[2][2] = num17;
|
||||
num18 ^= num17;
|
||||
array[2][3] = num18;
|
||||
for (int k = 3; k < 12; k += 3)
|
||||
{
|
||||
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num19 <<= 1;
|
||||
num13 ^= num20;
|
||||
array[k][0] = num13;
|
||||
num14 ^= num13;
|
||||
array[k][1] = num14;
|
||||
num15 ^= num14;
|
||||
array[k][2] = num15;
|
||||
num16 ^= num15;
|
||||
array[k][3] = num16;
|
||||
num17 ^= num16;
|
||||
array[k + 1][0] = num17;
|
||||
num18 ^= num17;
|
||||
array[k + 1][1] = num18;
|
||||
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num19 <<= 1;
|
||||
num13 ^= num20;
|
||||
array[k + 1][2] = num13;
|
||||
num14 ^= num13;
|
||||
array[k + 1][3] = num14;
|
||||
num15 ^= num14;
|
||||
array[k + 2][0] = num15;
|
||||
num16 ^= num15;
|
||||
array[k + 2][1] = num16;
|
||||
num17 ^= num16;
|
||||
array[k + 2][2] = num17;
|
||||
num18 ^= num17;
|
||||
array[k + 2][3] = num18;
|
||||
}
|
||||
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
||||
num13 ^= num20;
|
||||
array[12][0] = num13;
|
||||
num14 ^= num13;
|
||||
array[12][1] = num14;
|
||||
num15 ^= num14;
|
||||
array[12][2] = num15;
|
||||
num16 ^= num15;
|
||||
array[12][3] = num16;
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
uint num3 = Pack.LE_To_UInt32(key, 0);
|
||||
array[0][0] = num3;
|
||||
uint num4 = Pack.LE_To_UInt32(key, 4);
|
||||
array[0][1] = num4;
|
||||
uint num5 = Pack.LE_To_UInt32(key, 8);
|
||||
array[0][2] = num5;
|
||||
uint num6 = Pack.LE_To_UInt32(key, 12);
|
||||
array[0][3] = num6;
|
||||
uint num7 = Pack.LE_To_UInt32(key, 16);
|
||||
array[1][0] = num7;
|
||||
uint num8 = Pack.LE_To_UInt32(key, 20);
|
||||
array[1][1] = num8;
|
||||
uint num9 = Pack.LE_To_UInt32(key, 24);
|
||||
array[1][2] = num9;
|
||||
uint num10 = Pack.LE_To_UInt32(key, 28);
|
||||
array[1][3] = num10;
|
||||
uint num11 = 1u;
|
||||
uint num12;
|
||||
for (int j = 2; j < 14; j += 2)
|
||||
{
|
||||
num12 = SubWord(Shift(num10, 8)) ^ num11;
|
||||
num11 <<= 1;
|
||||
num3 ^= num12;
|
||||
array[j][0] = num3;
|
||||
num4 ^= num3;
|
||||
array[j][1] = num4;
|
||||
num5 ^= num4;
|
||||
array[j][2] = num5;
|
||||
num6 ^= num5;
|
||||
array[j][3] = num6;
|
||||
num12 = SubWord(num6);
|
||||
num7 ^= num12;
|
||||
array[j + 1][0] = num7;
|
||||
num8 ^= num7;
|
||||
array[j + 1][1] = num8;
|
||||
num9 ^= num8;
|
||||
array[j + 1][2] = num9;
|
||||
num10 ^= num9;
|
||||
array[j + 1][3] = num10;
|
||||
}
|
||||
num12 = SubWord(Shift(num10, 8)) ^ num11;
|
||||
num3 ^= num12;
|
||||
array[14][0] = num3;
|
||||
num4 ^= num3;
|
||||
array[14][1] = num4;
|
||||
num5 ^= num4;
|
||||
array[14][2] = num5;
|
||||
num6 ^= num5;
|
||||
array[14][3] = num6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException("Should never get here");
|
||||
}
|
||||
if (!forEncryption)
|
||||
{
|
||||
for (int m = 1; m < ROUNDS; m++)
|
||||
{
|
||||
uint[] array2 = array[m];
|
||||
for (int n = 0; n < 4; n++)
|
||||
{
|
||||
array2[n] = Inv_Mcol(array2[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter keyParameter))
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to AES init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption);
|
||||
this.forEncryption = forEncryption;
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (WorkingKey == null)
|
||||
{
|
||||
throw new InvalidOperationException("AES engine not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 16, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 16, "output buffer too short");
|
||||
UnPackBlock(input, inOff);
|
||||
if (forEncryption)
|
||||
{
|
||||
EncryptBlock(WorkingKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
DecryptBlock(WorkingKey);
|
||||
}
|
||||
PackBlock(output, outOff);
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
private void UnPackBlock(byte[] bytes, int off)
|
||||
{
|
||||
C0 = Pack.LE_To_UInt32(bytes, off);
|
||||
C1 = Pack.LE_To_UInt32(bytes, off + 4);
|
||||
C2 = Pack.LE_To_UInt32(bytes, off + 8);
|
||||
C3 = Pack.LE_To_UInt32(bytes, off + 12);
|
||||
}
|
||||
|
||||
private void PackBlock(byte[] bytes, int off)
|
||||
{
|
||||
Pack.UInt32_To_LE(C0, bytes, off);
|
||||
Pack.UInt32_To_LE(C1, bytes, off + 4);
|
||||
Pack.UInt32_To_LE(C2, bytes, off + 8);
|
||||
Pack.UInt32_To_LE(C3, bytes, off + 12);
|
||||
}
|
||||
|
||||
private void EncryptBlock(uint[][] KW)
|
||||
{
|
||||
uint[] array = KW[0];
|
||||
uint num = C0 ^ array[0];
|
||||
uint num2 = C1 ^ array[1];
|
||||
uint num3 = C2 ^ array[2];
|
||||
uint num4 = C3 ^ array[3];
|
||||
int num5 = 1;
|
||||
uint num6;
|
||||
uint num7;
|
||||
uint num8;
|
||||
while (num5 < ROUNDS - 1)
|
||||
{
|
||||
array = KW[num5++];
|
||||
num6 = Mcol((uint)(S[num & 0xFF] ^ (S[(num2 >> 8) & 0xFF] << 8) ^ (S[(num3 >> 16) & 0xFF] << 16) ^ (S[(num4 >> 24) & 0xFF] << 24))) ^ array[0];
|
||||
num7 = Mcol((uint)(S[num2 & 0xFF] ^ (S[(num3 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (S[(num >> 24) & 0xFF] << 24))) ^ array[1];
|
||||
num8 = Mcol((uint)(S[num3 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num >> 16) & 0xFF] << 16) ^ (S[(num2 >> 24) & 0xFF] << 24))) ^ array[2];
|
||||
num4 = Mcol((uint)(S[num4 & 0xFF] ^ (S[(num >> 8) & 0xFF] << 8) ^ (S[(num2 >> 16) & 0xFF] << 16) ^ (S[(num3 >> 24) & 0xFF] << 24))) ^ array[3];
|
||||
array = KW[num5++];
|
||||
num = Mcol((uint)(S[num6 & 0xFF] ^ (S[(num7 >> 8) & 0xFF] << 8) ^ (S[(num8 >> 16) & 0xFF] << 16) ^ (S[(num4 >> 24) & 0xFF] << 24))) ^ array[0];
|
||||
num2 = Mcol((uint)(S[num7 & 0xFF] ^ (S[(num8 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (S[(num6 >> 24) & 0xFF] << 24))) ^ array[1];
|
||||
num3 = Mcol((uint)(S[num8 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num6 >> 16) & 0xFF] << 16) ^ (S[(num7 >> 24) & 0xFF] << 24))) ^ array[2];
|
||||
num4 = Mcol((uint)(S[num4 & 0xFF] ^ (S[(num6 >> 8) & 0xFF] << 8) ^ (S[(num7 >> 16) & 0xFF] << 16) ^ (S[(num8 >> 24) & 0xFF] << 24))) ^ array[3];
|
||||
}
|
||||
array = KW[num5++];
|
||||
num6 = Mcol((uint)(S[num & 0xFF] ^ (S[(num2 >> 8) & 0xFF] << 8) ^ (S[(num3 >> 16) & 0xFF] << 16) ^ (S[(num4 >> 24) & 0xFF] << 24))) ^ array[0];
|
||||
num7 = Mcol((uint)(S[num2 & 0xFF] ^ (S[(num3 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (S[(num >> 24) & 0xFF] << 24))) ^ array[1];
|
||||
num8 = Mcol((uint)(S[num3 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num >> 16) & 0xFF] << 16) ^ (S[(num2 >> 24) & 0xFF] << 24))) ^ array[2];
|
||||
num4 = Mcol((uint)(S[num4 & 0xFF] ^ (S[(num >> 8) & 0xFF] << 8) ^ (S[(num2 >> 16) & 0xFF] << 16) ^ (S[(num3 >> 24) & 0xFF] << 24))) ^ array[3];
|
||||
array = KW[num5];
|
||||
C0 = (uint)(S[num6 & 0xFF] ^ (S[(num7 >> 8) & 0xFF] << 8) ^ (S[(num8 >> 16) & 0xFF] << 16) ^ (S[(num4 >> 24) & 0xFF] << 24)) ^ array[0];
|
||||
C1 = (uint)(S[num7 & 0xFF] ^ (S[(num8 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (S[(num6 >> 24) & 0xFF] << 24)) ^ array[1];
|
||||
C2 = (uint)(S[num8 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num6 >> 16) & 0xFF] << 16) ^ (S[(num7 >> 24) & 0xFF] << 24)) ^ array[2];
|
||||
C3 = (uint)(S[num4 & 0xFF] ^ (S[(num6 >> 8) & 0xFF] << 8) ^ (S[(num7 >> 16) & 0xFF] << 16) ^ (S[(num8 >> 24) & 0xFF] << 24)) ^ array[3];
|
||||
}
|
||||
|
||||
private void DecryptBlock(uint[][] KW)
|
||||
{
|
||||
uint[] array = KW[ROUNDS];
|
||||
uint num = C0 ^ array[0];
|
||||
uint num2 = C1 ^ array[1];
|
||||
uint num3 = C2 ^ array[2];
|
||||
uint num4 = C3 ^ array[3];
|
||||
int num5 = ROUNDS - 1;
|
||||
uint num6;
|
||||
uint num7;
|
||||
uint num8;
|
||||
while (num5 > 1)
|
||||
{
|
||||
array = KW[num5--];
|
||||
num6 = Inv_Mcol((uint)(Si[num & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num3 >> 16) & 0xFF] << 16) ^ (Si[(num2 >> 24) & 0xFF] << 24))) ^ array[0];
|
||||
num7 = Inv_Mcol((uint)(Si[num2 & 0xFF] ^ (Si[(num >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[(num3 >> 24) & 0xFF] << 24))) ^ array[1];
|
||||
num8 = Inv_Mcol((uint)(Si[num3 & 0xFF] ^ (Si[(num2 >> 8) & 0xFF] << 8) ^ (Si[(num >> 16) & 0xFF] << 16) ^ (Si[(num4 >> 24) & 0xFF] << 24))) ^ array[2];
|
||||
num4 = Inv_Mcol((uint)(Si[num4 & 0xFF] ^ (Si[(num3 >> 8) & 0xFF] << 8) ^ (Si[(num2 >> 16) & 0xFF] << 16) ^ (Si[(num >> 24) & 0xFF] << 24))) ^ array[3];
|
||||
array = KW[num5--];
|
||||
num = Inv_Mcol((uint)(Si[num6 & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num8 >> 16) & 0xFF] << 16) ^ (Si[(num7 >> 24) & 0xFF] << 24))) ^ array[0];
|
||||
num2 = Inv_Mcol((uint)(Si[num7 & 0xFF] ^ (Si[(num6 >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[(num8 >> 24) & 0xFF] << 24))) ^ array[1];
|
||||
num3 = Inv_Mcol((uint)(Si[num8 & 0xFF] ^ (Si[(num7 >> 8) & 0xFF] << 8) ^ (Si[(num6 >> 16) & 0xFF] << 16) ^ (Si[(num4 >> 24) & 0xFF] << 24))) ^ array[2];
|
||||
num4 = Inv_Mcol((uint)(Si[num4 & 0xFF] ^ (Si[(num8 >> 8) & 0xFF] << 8) ^ (Si[(num7 >> 16) & 0xFF] << 16) ^ (Si[(num6 >> 24) & 0xFF] << 24))) ^ array[3];
|
||||
}
|
||||
array = KW[1];
|
||||
num6 = Inv_Mcol((uint)(Si[num & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num3 >> 16) & 0xFF] << 16) ^ (Si[(num2 >> 24) & 0xFF] << 24))) ^ array[0];
|
||||
num7 = Inv_Mcol((uint)(Si[num2 & 0xFF] ^ (Si[(num >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[(num3 >> 24) & 0xFF] << 24))) ^ array[1];
|
||||
num8 = Inv_Mcol((uint)(Si[num3 & 0xFF] ^ (Si[(num2 >> 8) & 0xFF] << 8) ^ (Si[(num >> 16) & 0xFF] << 16) ^ (Si[(num4 >> 24) & 0xFF] << 24))) ^ array[2];
|
||||
num4 = Inv_Mcol((uint)(Si[num4 & 0xFF] ^ (Si[(num3 >> 8) & 0xFF] << 8) ^ (Si[(num2 >> 16) & 0xFF] << 16) ^ (Si[(num >> 24) & 0xFF] << 24))) ^ array[3];
|
||||
array = KW[0];
|
||||
C0 = (uint)(Si[num6 & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num8 >> 16) & 0xFF] << 16) ^ (Si[(num7 >> 24) & 0xFF] << 24)) ^ array[0];
|
||||
C1 = (uint)(Si[num7 & 0xFF] ^ (Si[(num6 >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[(num8 >> 24) & 0xFF] << 24)) ^ array[1];
|
||||
C2 = (uint)(Si[num8 & 0xFF] ^ (Si[(num7 >> 8) & 0xFF] << 8) ^ (Si[(num6 >> 16) & 0xFF] << 16) ^ (Si[(num4 >> 24) & 0xFF] << 24)) ^ array[2];
|
||||
C3 = (uint)(Si[num4 & 0xFF] ^ (Si[(num8 >> 8) & 0xFF] << 8) ^ (Si[(num7 >> 16) & 0xFF] << 16) ^ (Si[(num6 >> 24) & 0xFF] << 24)) ^ array[3];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class AesWrapEngine : Rfc3394WrapEngine
|
||||
{
|
||||
public AesWrapEngine()
|
||||
: base(new AesEngine())
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public sealed class BlowfishEngine : IBlockCipher
|
||||
{
|
||||
private const int BLOCK_SIZE = 8;
|
||||
|
||||
private static readonly uint[] KP = new uint[18]
|
||||
{
|
||||
608135816u, 2242054355u, 320440878u, 57701188u, 2752067618u, 698298832u, 137296536u, 3964562569u, 1160258022u, 953160567u,
|
||||
3193202383u, 887688300u, 3232508343u, 3380367581u, 1065670069u, 3041331479u, 2450970073u, 2306472731u
|
||||
};
|
||||
|
||||
private static readonly uint[] KS0 = new uint[256]
|
||||
{
|
||||
3509652390u, 2564797868u, 805139163u, 3491422135u, 3101798381u, 1780907670u, 3128725573u, 4046225305u, 614570311u, 3012652279u,
|
||||
134345442u, 2240740374u, 1667834072u, 1901547113u, 2757295779u, 4103290238u, 227898511u, 1921955416u, 1904987480u, 2182433518u,
|
||||
2069144605u, 3260701109u, 2620446009u, 720527379u, 3318853667u, 677414384u, 3393288472u, 3101374703u, 2390351024u, 1614419982u,
|
||||
1822297739u, 2954791486u, 3608508353u, 3174124327u, 2024746970u, 1432378464u, 3864339955u, 2857741204u, 1464375394u, 1676153920u,
|
||||
1439316330u, 715854006u, 3033291828u, 289532110u, 2706671279u, 2087905683u, 3018724369u, 1668267050u, 732546397u, 1947742710u,
|
||||
3462151702u, 2609353502u, 2950085171u, 1814351708u, 2050118529u, 680887927u, 999245976u, 1800124847u, 3300911131u, 1713906067u,
|
||||
1641548236u, 4213287313u, 1216130144u, 1575780402u, 4018429277u, 3917837745u, 3693486850u, 3949271944u, 596196993u, 3549867205u,
|
||||
258830323u, 2213823033u, 772490370u, 2760122372u, 1774776394u, 2652871518u, 566650946u, 4142492826u, 1728879713u, 2882767088u,
|
||||
1783734482u, 3629395816u, 2517608232u, 2874225571u, 1861159788u, 326777828u, 3124490320u, 2130389656u, 2716951837u, 967770486u,
|
||||
1724537150u, 2185432712u, 2364442137u, 1164943284u, 2105845187u, 998989502u, 3765401048u, 2244026483u, 1075463327u, 1455516326u,
|
||||
1322494562u, 910128902u, 469688178u, 1117454909u, 936433444u, 3490320968u, 3675253459u, 1240580251u, 122909385u, 2157517691u,
|
||||
634681816u, 4142456567u, 3825094682u, 3061402683u, 2540495037u, 79693498u, 3249098678u, 1084186820u, 1583128258u, 426386531u,
|
||||
1761308591u, 1047286709u, 322548459u, 995290223u, 1845252383u, 2603652396u, 3431023940u, 2942221577u, 3202600964u, 3727903485u,
|
||||
1712269319u, 422464435u, 3234572375u, 1170764815u, 3523960633u, 3117677531u, 1434042557u, 442511882u, 3600875718u, 1076654713u,
|
||||
1738483198u, 4213154764u, 2393238008u, 3677496056u, 1014306527u, 4251020053u, 793779912u, 2902807211u, 842905082u, 4246964064u,
|
||||
1395751752u, 1040244610u, 2656851899u, 3396308128u, 445077038u, 3742853595u, 3577915638u, 679411651u, 2892444358u, 2354009459u,
|
||||
1767581616u, 3150600392u, 3791627101u, 3102740896u, 284835224u, 4246832056u, 1258075500u, 768725851u, 2589189241u, 3069724005u,
|
||||
3532540348u, 1274779536u, 3789419226u, 2764799539u, 1660621633u, 3471099624u, 4011903706u, 913787905u, 3497959166u, 737222580u,
|
||||
2514213453u, 2928710040u, 3937242737u, 1804850592u, 3499020752u, 2949064160u, 2386320175u, 2390070455u, 2415321851u, 4061277028u,
|
||||
2290661394u, 2416832540u, 1336762016u, 1754252060u, 3520065937u, 3014181293u, 791618072u, 3188594551u, 3933548030u, 2332172193u,
|
||||
3852520463u, 3043980520u, 413987798u, 3465142937u, 3030929376u, 4245938359u, 2093235073u, 3534596313u, 375366246u, 2157278981u,
|
||||
2479649556u, 555357303u, 3870105701u, 2008414854u, 3344188149u, 4221384143u, 3956125452u, 2067696032u, 3594591187u, 2921233993u,
|
||||
2428461u, 544322398u, 577241275u, 1471733935u, 610547355u, 4027169054u, 1432588573u, 1507829418u, 2025931657u, 3646575487u,
|
||||
545086370u, 48609733u, 2200306550u, 1653985193u, 298326376u, 1316178497u, 3007786442u, 2064951626u, 458293330u, 2589141269u,
|
||||
3591329599u, 3164325604u, 727753846u, 2179363840u, 146436021u, 1461446943u, 4069977195u, 705550613u, 3059967265u, 3887724982u,
|
||||
4281599278u, 3313849956u, 1404054877u, 2845806497u, 146425753u, 1854211946u
|
||||
};
|
||||
|
||||
private static readonly uint[] KS1 = new uint[256]
|
||||
{
|
||||
1266315497u, 3048417604u, 3681880366u, 3289982499u, 2909710000u, 1235738493u, 2632868024u, 2414719590u, 3970600049u, 1771706367u,
|
||||
1449415276u, 3266420449u, 422970021u, 1963543593u, 2690192192u, 3826793022u, 1062508698u, 1531092325u, 1804592342u, 2583117782u,
|
||||
2714934279u, 4024971509u, 1294809318u, 4028980673u, 1289560198u, 2221992742u, 1669523910u, 35572830u, 157838143u, 1052438473u,
|
||||
1016535060u, 1802137761u, 1753167236u, 1386275462u, 3080475397u, 2857371447u, 1040679964u, 2145300060u, 2390574316u, 1461121720u,
|
||||
2956646967u, 4031777805u, 4028374788u, 33600511u, 2920084762u, 1018524850u, 629373528u, 3691585981u, 3515945977u, 2091462646u,
|
||||
2486323059u, 586499841u, 988145025u, 935516892u, 3367335476u, 2599673255u, 2839830854u, 265290510u, 3972581182u, 2759138881u,
|
||||
3795373465u, 1005194799u, 847297441u, 406762289u, 1314163512u, 1332590856u, 1866599683u, 4127851711u, 750260880u, 613907577u,
|
||||
1450815602u, 3165620655u, 3734664991u, 3650291728u, 3012275730u, 3704569646u, 1427272223u, 778793252u, 1343938022u, 2676280711u,
|
||||
2052605720u, 1946737175u, 3164576444u, 3914038668u, 3967478842u, 3682934266u, 1661551462u, 3294938066u, 4011595847u, 840292616u,
|
||||
3712170807u, 616741398u, 312560963u, 711312465u, 1351876610u, 322626781u, 1910503582u, 271666773u, 2175563734u, 1594956187u,
|
||||
70604529u, 3617834859u, 1007753275u, 1495573769u, 4069517037u, 2549218298u, 2663038764u, 504708206u, 2263041392u, 3941167025u,
|
||||
2249088522u, 1514023603u, 1998579484u, 1312622330u, 694541497u, 2582060303u, 2151582166u, 1382467621u, 776784248u, 2618340202u,
|
||||
3323268794u, 2497899128u, 2784771155u, 503983604u, 4076293799u, 907881277u, 423175695u, 432175456u, 1378068232u, 4145222326u,
|
||||
3954048622u, 3938656102u, 3820766613u, 2793130115u, 2977904593u, 26017576u, 3274890735u, 3194772133u, 1700274565u, 1756076034u,
|
||||
4006520079u, 3677328699u, 720338349u, 1533947780u, 354530856u, 688349552u, 3973924725u, 1637815568u, 332179504u, 3949051286u,
|
||||
53804574u, 2852348879u, 3044236432u, 1282449977u, 3583942155u, 3416972820u, 4006381244u, 1617046695u, 2628476075u, 3002303598u,
|
||||
1686838959u, 431878346u, 2686675385u, 1700445008u, 1080580658u, 1009431731u, 832498133u, 3223435511u, 2605976345u, 2271191193u,
|
||||
2516031870u, 1648197032u, 4164389018u, 2548247927u, 300782431u, 375919233u, 238389289u, 3353747414u, 2531188641u, 2019080857u,
|
||||
1475708069u, 455242339u, 2609103871u, 448939670u, 3451063019u, 1395535956u, 2413381860u, 1841049896u, 1491858159u, 885456874u,
|
||||
4264095073u, 4001119347u, 1565136089u, 3898914787u, 1108368660u, 540939232u, 1173283510u, 2745871338u, 3681308437u, 4207628240u,
|
||||
3343053890u, 4016749493u, 1699691293u, 1103962373u, 3625875870u, 2256883143u, 3830138730u, 1031889488u, 3479347698u, 1535977030u,
|
||||
4236805024u, 3251091107u, 2132092099u, 1774941330u, 1199868427u, 1452454533u, 157007616u, 2904115357u, 342012276u, 595725824u,
|
||||
1480756522u, 206960106u, 497939518u, 591360097u, 863170706u, 2375253569u, 3596610801u, 1814182875u, 2094937945u, 3421402208u,
|
||||
1082520231u, 3463918190u, 2785509508u, 435703966u, 3908032597u, 1641649973u, 2842273706u, 3305899714u, 1510255612u, 2148256476u,
|
||||
2655287854u, 3276092548u, 4258621189u, 236887753u, 3681803219u, 274041037u, 1734335097u, 3815195456u, 3317970021u, 1899903192u,
|
||||
1026095262u, 4050517792u, 356393447u, 2410691914u, 3873677099u, 3682840055u
|
||||
};
|
||||
|
||||
private static readonly uint[] KS2 = new uint[256]
|
||||
{
|
||||
3913112168u, 2491498743u, 4132185628u, 2489919796u, 1091903735u, 1979897079u, 3170134830u, 3567386728u, 3557303409u, 857797738u,
|
||||
1136121015u, 1342202287u, 507115054u, 2535736646u, 337727348u, 3213592640u, 1301675037u, 2528481711u, 1895095763u, 1721773893u,
|
||||
3216771564u, 62756741u, 2142006736u, 835421444u, 2531993523u, 1442658625u, 3659876326u, 2882144922u, 676362277u, 1392781812u,
|
||||
170690266u, 3921047035u, 1759253602u, 3611846912u, 1745797284u, 664899054u, 1329594018u, 3901205900u, 3045908486u, 2062866102u,
|
||||
2865634940u, 3543621612u, 3464012697u, 1080764994u, 553557557u, 3656615353u, 3996768171u, 991055499u, 499776247u, 1265440854u,
|
||||
648242737u, 3940784050u, 980351604u, 3713745714u, 1749149687u, 3396870395u, 4211799374u, 3640570775u, 1161844396u, 3125318951u,
|
||||
1431517754u, 545492359u, 4268468663u, 3499529547u, 1437099964u, 2702547544u, 3433638243u, 2581715763u, 2787789398u, 1060185593u,
|
||||
1593081372u, 2418618748u, 4260947970u, 69676912u, 2159744348u, 86519011u, 2512459080u, 3838209314u, 1220612927u, 3339683548u,
|
||||
133810670u, 1090789135u, 1078426020u, 1569222167u, 845107691u, 3583754449u, 4072456591u, 1091646820u, 628848692u, 1613405280u,
|
||||
3757631651u, 526609435u, 236106946u, 48312990u, 2942717905u, 3402727701u, 1797494240u, 859738849u, 992217954u, 4005476642u,
|
||||
2243076622u, 3870952857u, 3732016268u, 765654824u, 3490871365u, 2511836413u, 1685915746u, 3888969200u, 1414112111u, 2273134842u,
|
||||
3281911079u, 4080962846u, 172450625u, 2569994100u, 980381355u, 4109958455u, 2819808352u, 2716589560u, 2568741196u, 3681446669u,
|
||||
3329971472u, 1835478071u, 660984891u, 3704678404u, 4045999559u, 3422617507u, 3040415634u, 1762651403u, 1719377915u, 3470491036u,
|
||||
2693910283u, 3642056355u, 3138596744u, 1364962596u, 2073328063u, 1983633131u, 926494387u, 3423689081u, 2150032023u, 4096667949u,
|
||||
1749200295u, 3328846651u, 309677260u, 2016342300u, 1779581495u, 3079819751u, 111262694u, 1274766160u, 443224088u, 298511866u,
|
||||
1025883608u, 3806446537u, 1145181785u, 168956806u, 3641502830u, 3584813610u, 1689216846u, 3666258015u, 3200248200u, 1692713982u,
|
||||
2646376535u, 4042768518u, 1618508792u, 1610833997u, 3523052358u, 4130873264u, 2001055236u, 3610705100u, 2202168115u, 4028541809u,
|
||||
2961195399u, 1006657119u, 2006996926u, 3186142756u, 1430667929u, 3210227297u, 1314452623u, 4074634658u, 4101304120u, 2273951170u,
|
||||
1399257539u, 3367210612u, 3027628629u, 1190975929u, 2062231137u, 2333990788u, 2221543033u, 2438960610u, 1181637006u, 548689776u,
|
||||
2362791313u, 3372408396u, 3104550113u, 3145860560u, 296247880u, 1970579870u, 3078560182u, 3769228297u, 1714227617u, 3291629107u,
|
||||
3898220290u, 166772364u, 1251581989u, 493813264u, 448347421u, 195405023u, 2709975567u, 677966185u, 3703036547u, 1463355134u,
|
||||
2715995803u, 1338867538u, 1343315457u, 2802222074u, 2684532164u, 233230375u, 2599980071u, 2000651841u, 3277868038u, 1638401717u,
|
||||
4028070440u, 3237316320u, 6314154u, 819756386u, 300326615u, 590932579u, 1405279636u, 3267499572u, 3150704214u, 2428286686u,
|
||||
3959192993u, 3461946742u, 1862657033u, 1266418056u, 963775037u, 2089974820u, 2263052895u, 1917689273u, 448879540u, 3550394620u,
|
||||
3981727096u, 150775221u, 3627908307u, 1303187396u, 508620638u, 2975983352u, 2726630617u, 1817252668u, 1876281319u, 1457606340u,
|
||||
908771278u, 3720792119u, 3617206836u, 2455994898u, 1729034894u, 1080033504u
|
||||
};
|
||||
|
||||
private static readonly uint[] KS3 = new uint[256]
|
||||
{
|
||||
976866871u, 3556439503u, 2881648439u, 1522871579u, 1555064734u, 1336096578u, 3548522304u, 2579274686u, 3574697629u, 3205460757u,
|
||||
3593280638u, 3338716283u, 3079412587u, 564236357u, 2993598910u, 1781952180u, 1464380207u, 3163844217u, 3332601554u, 1699332808u,
|
||||
1393555694u, 1183702653u, 3581086237u, 1288719814u, 691649499u, 2847557200u, 2895455976u, 3193889540u, 2717570544u, 1781354906u,
|
||||
1676643554u, 2592534050u, 3230253752u, 1126444790u, 2770207658u, 2633158820u, 2210423226u, 2615765581u, 2414155088u, 3127139286u,
|
||||
673620729u, 2805611233u, 1269405062u, 4015350505u, 3341807571u, 4149409754u, 1057255273u, 2012875353u, 2162469141u, 2276492801u,
|
||||
2601117357u, 993977747u, 3918593370u, 2654263191u, 753973209u, 36408145u, 2530585658u, 25011837u, 3520020182u, 2088578344u,
|
||||
530523599u, 2918365339u, 1524020338u, 1518925132u, 3760827505u, 3759777254u, 1202760957u, 3985898139u, 3906192525u, 674977740u,
|
||||
4174734889u, 2031300136u, 2019492241u, 3983892565u, 4153806404u, 3822280332u, 352677332u, 2297720250u, 60907813u, 90501309u,
|
||||
3286998549u, 1016092578u, 2535922412u, 2839152426u, 457141659u, 509813237u, 4120667899u, 652014361u, 1966332200u, 2975202805u,
|
||||
55981186u, 2327461051u, 676427537u, 3255491064u, 2882294119u, 3433927263u, 1307055953u, 942726286u, 933058658u, 2468411793u,
|
||||
3933900994u, 4215176142u, 1361170020u, 2001714738u, 2830558078u, 3274259782u, 1222529897u, 1679025792u, 2729314320u, 3714953764u,
|
||||
1770335741u, 151462246u, 3013232138u, 1682292957u, 1483529935u, 471910574u, 1539241949u, 458788160u, 3436315007u, 1807016891u,
|
||||
3718408830u, 978976581u, 1043663428u, 3165965781u, 1927990952u, 4200891579u, 2372276910u, 3208408903u, 3533431907u, 1412390302u,
|
||||
2931980059u, 4132332400u, 1947078029u, 3881505623u, 4168226417u, 2941484381u, 1077988104u, 1320477388u, 886195818u, 18198404u,
|
||||
3786409000u, 2509781533u, 112762804u, 3463356488u, 1866414978u, 891333506u, 18488651u, 661792760u, 1628790961u, 3885187036u,
|
||||
3141171499u, 876946877u, 2693282273u, 1372485963u, 791857591u, 2686433993u, 3759982718u, 3167212022u, 3472953795u, 2716379847u,
|
||||
445679433u, 3561995674u, 3504004811u, 3574258232u, 54117162u, 3331405415u, 2381918588u, 3769707343u, 4154350007u, 1140177722u,
|
||||
4074052095u, 668550556u, 3214352940u, 367459370u, 261225585u, 2610173221u, 4209349473u, 3468074219u, 3265815641u, 314222801u,
|
||||
3066103646u, 3808782860u, 282218597u, 3406013506u, 3773591054u, 379116347u, 1285071038u, 846784868u, 2669647154u, 3771962079u,
|
||||
3550491691u, 2305946142u, 453669953u, 1268987020u, 3317592352u, 3279303384u, 3744833421u, 2610507566u, 3859509063u, 266596637u,
|
||||
3847019092u, 517658769u, 3462560207u, 3443424879u, 370717030u, 4247526661u, 2224018117u, 4143653529u, 4112773975u, 2788324899u,
|
||||
2477274417u, 1456262402u, 2901442914u, 1517677493u, 1846949527u, 2295493580u, 3734397586u, 2176403920u, 1280348187u, 1908823572u,
|
||||
3871786941u, 846861322u, 1172426758u, 3287448474u, 3383383037u, 1655181056u, 3139813346u, 901632758u, 1897031941u, 2986607138u,
|
||||
3066810236u, 3447102507u, 1393639104u, 373351379u, 950779232u, 625454576u, 3124240540u, 4148612726u, 2007998917u, 544563296u,
|
||||
2244738638u, 2330496472u, 2058025392u, 1291430526u, 424198748u, 50039436u, 29584100u, 3605783033u, 2429876329u, 2791104160u,
|
||||
1057563949u, 3255363231u, 3075367218u, 3463963227u, 1469046755u, 985887462u
|
||||
};
|
||||
|
||||
private static readonly int ROUNDS = 16;
|
||||
|
||||
private static readonly int SBOX_SK = 256;
|
||||
|
||||
private static readonly int P_SZ = ROUNDS + 2;
|
||||
|
||||
private readonly uint[] S0;
|
||||
|
||||
private readonly uint[] S1;
|
||||
|
||||
private readonly uint[] S2;
|
||||
|
||||
private readonly uint[] S3;
|
||||
|
||||
private readonly uint[] P;
|
||||
|
||||
private bool encrypting;
|
||||
|
||||
private byte[] workingKey;
|
||||
|
||||
public string AlgorithmName => "Blowfish";
|
||||
|
||||
public bool IsPartialBlockOkay => false;
|
||||
|
||||
public BlowfishEngine()
|
||||
{
|
||||
S0 = new uint[SBOX_SK];
|
||||
S1 = new uint[SBOX_SK];
|
||||
S2 = new uint[SBOX_SK];
|
||||
S3 = new uint[SBOX_SK];
|
||||
P = new uint[P_SZ];
|
||||
}
|
||||
|
||||
public void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter))
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to Blowfish init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
encrypting = forEncryption;
|
||||
workingKey = ((KeyParameter)parameters).GetKey();
|
||||
SetKey(workingKey);
|
||||
}
|
||||
|
||||
public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (workingKey == null)
|
||||
{
|
||||
throw new InvalidOperationException("Blowfish not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 8, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 8, "output buffer too short");
|
||||
if (encrypting)
|
||||
{
|
||||
EncryptBlock(input, inOff, output, outOff);
|
||||
}
|
||||
else
|
||||
{
|
||||
DecryptBlock(input, inOff, output, outOff);
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
public int GetBlockSize()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
private uint F(uint x)
|
||||
{
|
||||
return ((S0[x >> 24] + S1[(x >> 16) & 0xFF]) ^ S2[(x >> 8) & 0xFF]) + S3[x & 0xFF];
|
||||
}
|
||||
|
||||
private void ProcessTable(uint xl, uint xr, uint[] table)
|
||||
{
|
||||
int num = table.Length;
|
||||
for (int i = 0; i < num; i += 2)
|
||||
{
|
||||
xl ^= P[0];
|
||||
for (int j = 1; j < ROUNDS; j += 2)
|
||||
{
|
||||
xr ^= F(xl) ^ P[j];
|
||||
xl ^= F(xr) ^ P[j + 1];
|
||||
}
|
||||
xr ^= P[ROUNDS + 1];
|
||||
table[i] = xr;
|
||||
table[i + 1] = xl;
|
||||
xr = xl;
|
||||
xl = table[i];
|
||||
}
|
||||
}
|
||||
|
||||
private void SetKey(byte[] key)
|
||||
{
|
||||
Array.Copy(KS0, 0, S0, 0, SBOX_SK);
|
||||
Array.Copy(KS1, 0, S1, 0, SBOX_SK);
|
||||
Array.Copy(KS2, 0, S2, 0, SBOX_SK);
|
||||
Array.Copy(KS3, 0, S3, 0, SBOX_SK);
|
||||
Array.Copy(KP, 0, P, 0, P_SZ);
|
||||
int num = key.Length;
|
||||
int num2 = 0;
|
||||
for (int i = 0; i < P_SZ; i++)
|
||||
{
|
||||
uint num3 = 0u;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
num3 = (num3 << 8) | key[num2++];
|
||||
if (num2 >= num)
|
||||
{
|
||||
num2 = 0;
|
||||
}
|
||||
}
|
||||
uint[] p;
|
||||
uint[] array = (p = P);
|
||||
int num4 = i;
|
||||
nint num5 = num4;
|
||||
array[num4] = p[num5] ^ num3;
|
||||
}
|
||||
ProcessTable(0u, 0u, P);
|
||||
ProcessTable(P[P_SZ - 2], P[P_SZ - 1], S0);
|
||||
ProcessTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
|
||||
ProcessTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
|
||||
ProcessTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
|
||||
}
|
||||
|
||||
private void EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
|
||||
{
|
||||
uint num = Pack.BE_To_UInt32(src, srcIndex);
|
||||
uint num2 = Pack.BE_To_UInt32(src, srcIndex + 4);
|
||||
num ^= P[0];
|
||||
for (int i = 1; i < ROUNDS; i += 2)
|
||||
{
|
||||
num2 ^= F(num) ^ P[i];
|
||||
num ^= F(num2) ^ P[i + 1];
|
||||
}
|
||||
num2 ^= P[ROUNDS + 1];
|
||||
Pack.UInt32_To_BE(num2, dst, dstIndex);
|
||||
Pack.UInt32_To_BE(num, dst, dstIndex + 4);
|
||||
}
|
||||
|
||||
private void DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
|
||||
{
|
||||
uint num = Pack.BE_To_UInt32(src, srcIndex);
|
||||
uint num2 = Pack.BE_To_UInt32(src, srcIndex + 4);
|
||||
num ^= P[ROUNDS + 1];
|
||||
for (int num3 = ROUNDS; num3 > 0; num3 -= 2)
|
||||
{
|
||||
num2 ^= F(num) ^ P[num3];
|
||||
num ^= F(num2) ^ P[num3 - 1];
|
||||
}
|
||||
num2 ^= P[0];
|
||||
Pack.UInt32_To_BE(num2, dst, dstIndex);
|
||||
Pack.UInt32_To_BE(num, dst, dstIndex + 4);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,548 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class CamelliaEngine : IBlockCipher
|
||||
{
|
||||
private const int BLOCK_SIZE = 16;
|
||||
|
||||
private bool initialised = false;
|
||||
|
||||
private bool _keyIs128;
|
||||
|
||||
private uint[] subkey = new uint[96];
|
||||
|
||||
private uint[] kw = new uint[8];
|
||||
|
||||
private uint[] ke = new uint[12];
|
||||
|
||||
private uint[] state = new uint[4];
|
||||
|
||||
private static readonly uint[] SIGMA = new uint[12]
|
||||
{
|
||||
2694735487u, 1003262091u, 3061508184u, 1286239154u, 3337565999u, 3914302142u, 1426019237u, 4057165596u, 283453434u, 3731369245u,
|
||||
2958461122u, 3018244605u
|
||||
};
|
||||
|
||||
private static readonly uint[] SBOX1_1110 = new uint[256]
|
||||
{
|
||||
1886416896u, 2189591040u, 741092352u, 3974949888u, 3014898432u, 656877312u, 3233857536u, 3857048832u, 3840205824u, 2240120064u,
|
||||
1465341696u, 892679424u, 3941263872u, 202116096u, 2930683392u, 1094795520u, 589505280u, 4025478912u, 1802201856u, 2475922176u,
|
||||
1162167552u, 421075200u, 2779096320u, 555819264u, 3991792896u, 235802112u, 1330597632u, 1313754624u, 488447232u, 1701143808u,
|
||||
2459079168u, 3183328512u, 2256963072u, 3099113472u, 2947526400u, 2408550144u, 2088532992u, 3958106880u, 522133248u, 3469659648u,
|
||||
1044266496u, 808464384u, 3705461760u, 1600085760u, 1583242752u, 3318072576u, 185273088u, 437918208u, 2795939328u, 3789676800u,
|
||||
960051456u, 3402287616u, 3587560704u, 1195853568u, 1566399744u, 1027423488u, 3654932736u, 16843008u, 1515870720u, 3604403712u,
|
||||
1364283648u, 1448498688u, 1819044864u, 1296911616u, 2341178112u, 218959104u, 2593823232u, 1717986816u, 4227595008u, 3435973632u,
|
||||
2964369408u, 757935360u, 1953788928u, 303174144u, 724249344u, 538976256u, 4042321920u, 2981212416u, 2223277056u, 2576980224u,
|
||||
3755990784u, 1280068608u, 3419130624u, 3267543552u, 875836416u, 2122219008u, 1987474944u, 84215040u, 1835887872u, 3082270464u,
|
||||
2846468352u, 825307392u, 3520188672u, 387389184u, 67372032u, 3621246720u, 336860160u, 1482184704u, 976894464u, 1633771776u,
|
||||
3739147776u, 454761216u, 286331136u, 471604224u, 842150400u, 252645120u, 2627509248u, 370546176u, 1397969664u, 404232192u,
|
||||
4076007936u, 572662272u, 4278124032u, 1145324544u, 3486502656u, 2998055424u, 3284386560u, 3048584448u, 2054846976u, 2442236160u,
|
||||
606348288u, 134744064u, 3907577856u, 2829625344u, 1616928768u, 4244438016u, 1768515840u, 1347440640u, 2863311360u, 3503345664u,
|
||||
2694881280u, 2105376000u, 2711724288u, 2307492096u, 1650614784u, 2543294208u, 1414812672u, 1532713728u, 505290240u, 2509608192u,
|
||||
3772833792u, 4294967040u, 1684300800u, 3537031680u, 269488128u, 3301229568u, 0u, 1212696576u, 2745410304u, 4160222976u,
|
||||
1970631936u, 3688618752u, 2324335104u, 50529024u, 3873891840u, 3671775744u, 151587072u, 1061109504u, 3722304768u, 2492765184u,
|
||||
2273806080u, 1549556736u, 2206434048u, 33686016u, 3452816640u, 1246382592u, 2425393152u, 858993408u, 1936945920u, 1734829824u,
|
||||
4143379968u, 4092850944u, 2644352256u, 2139062016u, 3217014528u, 3806519808u, 1381126656u, 2610666240u, 3638089728u, 640034304u,
|
||||
3368601600u, 926365440u, 3334915584u, 993737472u, 2172748032u, 2526451200u, 1869573888u, 1263225600u, 320017152u, 3200171520u,
|
||||
1667457792u, 774778368u, 3924420864u, 2038003968u, 2812782336u, 2358021120u, 2678038272u, 1852730880u, 3166485504u, 2391707136u,
|
||||
690563328u, 4126536960u, 4193908992u, 3065427456u, 791621376u, 4261281024u, 3031741440u, 1499027712u, 2021160960u, 2560137216u,
|
||||
101058048u, 1785358848u, 3890734848u, 1179010560u, 1903259904u, 3132799488u, 3570717696u, 623191296u, 2880154368u, 1111638528u,
|
||||
2290649088u, 2728567296u, 2374864128u, 4210752000u, 1920102912u, 117901056u, 3115956480u, 1431655680u, 4177065984u, 4008635904u,
|
||||
2896997376u, 168430080u, 909522432u, 1229539584u, 707406336u, 1751672832u, 1010580480u, 943208448u, 4059164928u, 2762253312u,
|
||||
1077952512u, 673720320u, 3553874688u, 2071689984u, 3149642496u, 3385444608u, 1128481536u, 3250700544u, 353703168u, 3823362816u,
|
||||
2913840384u, 4109693952u, 2004317952u, 3351758592u, 2155905024u, 2661195264u
|
||||
};
|
||||
|
||||
private static readonly uint[] SBOX4_4404 = new uint[256]
|
||||
{
|
||||
1886388336u, 741081132u, 3014852787u, 3233808576u, 3840147684u, 1465319511u, 3941204202u, 2930639022u, 589496355u, 1802174571u,
|
||||
1162149957u, 2779054245u, 3991732461u, 1330577487u, 488439837u, 2459041938u, 2256928902u, 2947481775u, 2088501372u, 522125343u,
|
||||
1044250686u, 3705405660u, 1583218782u, 185270283u, 2795896998u, 960036921u, 3587506389u, 1566376029u, 3654877401u, 1515847770u,
|
||||
1364262993u, 1819017324u, 2341142667u, 2593783962u, 4227531003u, 2964324528u, 1953759348u, 724238379u, 4042260720u, 2223243396u,
|
||||
3755933919u, 3419078859u, 875823156u, 1987444854u, 1835860077u, 2846425257u, 3520135377u, 67371012u, 336855060u, 976879674u,
|
||||
3739091166u, 286326801u, 842137650u, 2627469468u, 1397948499u, 4075946226u, 4278059262u, 3486449871u, 3284336835u, 2054815866u,
|
||||
606339108u, 3907518696u, 1616904288u, 1768489065u, 2863268010u, 2694840480u, 2711683233u, 1650589794u, 1414791252u, 505282590u,
|
||||
3772776672u, 1684275300u, 269484048u, 0u, 2745368739u, 1970602101u, 2324299914u, 3873833190u, 151584777u, 3722248413u,
|
||||
2273771655u, 2206400643u, 3452764365u, 2425356432u, 1936916595u, 4143317238u, 2644312221u, 3216965823u, 1381105746u, 3638034648u,
|
||||
3368550600u, 3334865094u, 2172715137u, 1869545583u, 320012307u, 1667432547u, 3924361449u, 2812739751u, 2677997727u, 3166437564u,
|
||||
690552873u, 4193845497u, 791609391u, 3031695540u, 2021130360u, 101056518u, 3890675943u, 1903231089u, 3570663636u, 2880110763u,
|
||||
2290614408u, 2374828173u, 1920073842u, 3115909305u, 4177002744u, 2896953516u, 909508662u, 707395626u, 1010565180u, 4059103473u,
|
||||
1077936192u, 3553820883u, 3149594811u, 1128464451u, 353697813u, 2913796269u, 2004287607u, 2155872384u, 2189557890u, 3974889708u,
|
||||
656867367u, 3856990437u, 2240086149u, 892665909u, 202113036u, 1094778945u, 4025417967u, 2475884691u, 421068825u, 555810849u,
|
||||
235798542u, 1313734734u, 1701118053u, 3183280317u, 3099066552u, 2408513679u, 3958046955u, 3469607118u, 808452144u, 1600061535u,
|
||||
3318022341u, 437911578u, 3789619425u, 3402236106u, 1195835463u, 1027407933u, 16842753u, 3604349142u, 1448476758u, 1296891981u,
|
||||
218955789u, 1717960806u, 3435921612u, 757923885u, 303169554u, 538968096u, 2981167281u, 2576941209u, 1280049228u, 3267494082u,
|
||||
2122186878u, 84213765u, 3082223799u, 825294897u, 387383319u, 3621191895u, 1482162264u, 1633747041u, 454754331u, 471597084u,
|
||||
252641295u, 370540566u, 404226072u, 572653602u, 1145307204u, 2998010034u, 3048538293u, 2442199185u, 134742024u, 2829582504u,
|
||||
4244373756u, 1347420240u, 3503292624u, 2105344125u, 2307457161u, 2543255703u, 1532690523u, 2509570197u, 4294902015u, 3536978130u,
|
||||
3301179588u, 1212678216u, 4160159991u, 3688562907u, 50528259u, 3671720154u, 1061093439u, 2492727444u, 1549533276u, 33685506u,
|
||||
1246363722u, 858980403u, 1734803559u, 4092788979u, 2139029631u, 3806462178u, 2610626715u, 640024614u, 926351415u, 993722427u,
|
||||
2526412950u, 1263206475u, 3200123070u, 774766638u, 2037973113u, 2357985420u, 1852702830u, 2391670926u, 4126474485u, 3065381046u,
|
||||
4261216509u, 1499005017u, 2560098456u, 1785331818u, 1178992710u, 3132752058u, 623181861u, 1111621698u, 2728525986u, 4210688250u,
|
||||
117899271u, 1431634005u, 4008575214u, 168427530u, 1229520969u, 1751646312u, 943194168u, 2762211492u, 673710120u, 2071658619u,
|
||||
3385393353u, 3250651329u, 3823304931u, 4109631732u, 3351707847u, 2661154974u
|
||||
};
|
||||
|
||||
private static readonly uint[] SBOX2_0222 = new uint[256]
|
||||
{
|
||||
14737632u, 328965u, 5789784u, 14277081u, 6776679u, 5131854u, 8487297u, 13355979u, 13224393u, 723723u,
|
||||
11447982u, 6974058u, 14013909u, 1579032u, 6118749u, 8553090u, 4605510u, 14671839u, 14079702u, 2565927u,
|
||||
9079434u, 3289650u, 4934475u, 4342338u, 14408667u, 1842204u, 10395294u, 10263708u, 3815994u, 13290186u,
|
||||
2434341u, 8092539u, 855309u, 7434609u, 6250335u, 2039583u, 16316664u, 14145495u, 4079166u, 10329501u,
|
||||
8158332u, 6316128u, 12171705u, 12500670u, 12369084u, 9145227u, 1447446u, 3421236u, 5066061u, 12829635u,
|
||||
7500402u, 9803157u, 11250603u, 9342606u, 12237498u, 8026746u, 11776947u, 131586u, 11842740u, 11382189u,
|
||||
10658466u, 11316396u, 14211288u, 10132122u, 1513239u, 1710618u, 3487029u, 13421772u, 16250871u, 10066329u,
|
||||
6381921u, 5921370u, 15263976u, 2368548u, 5658198u, 4210752u, 14803425u, 6513507u, 592137u, 3355443u,
|
||||
12566463u, 10000536u, 9934743u, 8750469u, 6842472u, 16579836u, 15527148u, 657930u, 14342874u, 7303023u,
|
||||
5460819u, 6447714u, 10724259u, 3026478u, 526344u, 11513775u, 2631720u, 11579568u, 7631988u, 12763842u,
|
||||
12434877u, 3552822u, 2236962u, 3684408u, 6579300u, 1973790u, 3750201u, 2894892u, 10921638u, 3158064u,
|
||||
15066597u, 4473924u, 16645629u, 8947848u, 10461087u, 6645093u, 8882055u, 7039851u, 16053492u, 2302755u,
|
||||
4737096u, 1052688u, 13750737u, 5329233u, 12632256u, 16382457u, 13816530u, 10526880u, 5592405u, 10592673u,
|
||||
4276545u, 16448250u, 4408131u, 1250067u, 12895428u, 3092271u, 11053224u, 11974326u, 3947580u, 2829099u,
|
||||
12698049u, 16777215u, 13158600u, 10855845u, 2105376u, 9013641u, 0u, 9474192u, 4671303u, 15724527u,
|
||||
15395562u, 12040119u, 1381653u, 394758u, 13487565u, 11908533u, 1184274u, 8289918u, 12303291u, 2697513u,
|
||||
986895u, 12105912u, 460551u, 263172u, 10197915u, 9737364u, 2171169u, 6710886u, 15132390u, 13553358u,
|
||||
15592941u, 15198183u, 3881787u, 16711422u, 8355711u, 12961221u, 10790052u, 3618615u, 11645361u, 5000268u,
|
||||
9539985u, 7237230u, 9276813u, 7763574u, 197379u, 2960685u, 14606046u, 9868950u, 2500134u, 8224125u,
|
||||
13027014u, 6052956u, 13882323u, 15921906u, 5197647u, 1644825u, 4144959u, 14474460u, 7960953u, 1907997u,
|
||||
5395026u, 15461355u, 15987699u, 7171437u, 6184542u, 16514043u, 6908265u, 11711154u, 15790320u, 3223857u,
|
||||
789516u, 13948116u, 13619151u, 9211020u, 14869218u, 7697781u, 11119017u, 4868682u, 5723991u, 8684676u,
|
||||
1118481u, 4539717u, 1776411u, 16119285u, 15000804u, 921102u, 7566195u, 11184810u, 15856113u, 14540253u,
|
||||
5855577u, 1315860u, 7105644u, 9605778u, 5526612u, 13684944u, 7895160u, 7368816u, 14935011u, 4802889u,
|
||||
8421504u, 5263440u, 10987431u, 16185078u, 7829367u, 9671571u, 8816262u, 8618883u, 2763306u, 13092807u,
|
||||
5987163u, 15329769u, 15658734u, 9408399u, 65793u, 4013373u
|
||||
};
|
||||
|
||||
private static readonly uint[] SBOX3_3033 = new uint[256]
|
||||
{
|
||||
939538488u, 1090535745u, 369104406u, 1979741814u, 3640711641u, 2466288531u, 1610637408u, 4060148466u, 1912631922u, 3254829762u,
|
||||
2868947883u, 2583730842u, 1962964341u, 100664838u, 1459640151u, 2684395680u, 2432733585u, 4144035831u, 3036722613u, 3372272073u,
|
||||
2717950626u, 2348846220u, 3523269330u, 2415956112u, 4127258358u, 117442311u, 2801837991u, 654321447u, 2382401166u, 2986390194u,
|
||||
1224755529u, 3724599006u, 1124090691u, 1543527516u, 3607156695u, 3338717127u, 1040203326u, 4110480885u, 2399178639u, 1728079719u,
|
||||
520101663u, 402659352u, 1845522030u, 2936057775u, 788541231u, 3791708898u, 2231403909u, 218107149u, 1392530259u, 4026593520u,
|
||||
2617285788u, 1694524773u, 3925928682u, 2734728099u, 2919280302u, 2650840734u, 3959483628u, 2147516544u, 754986285u, 1795189611u,
|
||||
2818615464u, 721431339u, 905983542u, 2785060518u, 3305162181u, 2248181382u, 1291865421u, 855651123u, 4244700669u, 1711302246u,
|
||||
1476417624u, 2516620950u, 973093434u, 150997257u, 2499843477u, 268439568u, 2013296760u, 3623934168u, 1107313218u, 3422604492u,
|
||||
4009816047u, 637543974u, 3842041317u, 1627414881u, 436214298u, 1056980799u, 989870907u, 2181071490u, 3053500086u, 3674266587u,
|
||||
3556824276u, 2550175896u, 3892373736u, 2332068747u, 33554946u, 3942706155u, 167774730u, 738208812u, 486546717u, 2952835248u,
|
||||
1862299503u, 2365623693u, 2281736328u, 234884622u, 419436825u, 2264958855u, 1308642894u, 184552203u, 2835392937u, 201329676u,
|
||||
2030074233u, 285217041u, 2130739071u, 570434082u, 3875596263u, 1493195097u, 3774931425u, 3657489114u, 1023425853u, 3355494600u,
|
||||
301994514u, 67109892u, 1946186868u, 1409307732u, 805318704u, 2113961598u, 3019945140u, 671098920u, 1426085205u, 1744857192u,
|
||||
1342197840u, 3187719870u, 3489714384u, 3288384708u, 822096177u, 3405827019u, 704653866u, 2902502829u, 251662095u, 3389049546u,
|
||||
1879076976u, 4278255615u, 838873650u, 1761634665u, 134219784u, 1644192354u, 0u, 603989028u, 3506491857u, 4211145723u,
|
||||
3120609978u, 3976261101u, 1157645637u, 2164294017u, 1929409395u, 1828744557u, 2214626436u, 2667618207u, 3993038574u, 1241533002u,
|
||||
3271607235u, 771763758u, 3238052289u, 16777473u, 3858818790u, 620766501u, 1207978056u, 2566953369u, 3103832505u, 3003167667u,
|
||||
2063629179u, 4177590777u, 3456159438u, 3204497343u, 3741376479u, 1895854449u, 687876393u, 3439381965u, 1811967084u, 318771987u,
|
||||
1677747300u, 2600508315u, 1660969827u, 2634063261u, 3221274816u, 1258310475u, 3070277559u, 2768283045u, 2298513801u, 1593859935u,
|
||||
2969612721u, 385881879u, 4093703412u, 3154164924u, 3540046803u, 1174423110u, 3472936911u, 922761015u, 1577082462u, 1191200583u,
|
||||
2483066004u, 4194368250u, 4227923196u, 1526750043u, 2533398423u, 4261478142u, 1509972570u, 2885725356u, 1006648380u, 1275087948u,
|
||||
50332419u, 889206069u, 4076925939u, 587211555u, 3087055032u, 1560304989u, 1778412138u, 2449511058u, 3573601749u, 553656609u,
|
||||
1140868164u, 1358975313u, 3321939654u, 2097184125u, 956315961u, 2197848963u, 3691044060u, 2852170410u, 2080406652u, 1996519287u,
|
||||
1442862678u, 83887365u, 452991771u, 2751505572u, 352326933u, 872428596u, 503324190u, 469769244u, 4160813304u, 1375752786u,
|
||||
536879136u, 335549460u, 3909151209u, 3170942397u, 3707821533u, 3825263844u, 2701173153u, 3758153952u, 2315291274u, 4043370993u,
|
||||
3590379222u, 2046851706u, 3137387451u, 3808486371u, 1073758272u, 1325420367u
|
||||
};
|
||||
|
||||
public virtual string AlgorithmName => "Camellia";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
private static uint rightRotate(uint x, int s)
|
||||
{
|
||||
return (x >> s) + (x << 32 - s);
|
||||
}
|
||||
|
||||
private static uint leftRotate(uint x, int s)
|
||||
{
|
||||
return (x << s) + (x >> 32 - s);
|
||||
}
|
||||
|
||||
private static void roldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
|
||||
{
|
||||
ko[ooff] = (ki[ioff] << rot) | (ki[1 + ioff] >> 32 - rot);
|
||||
ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> 32 - rot);
|
||||
ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> 32 - rot);
|
||||
ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[ioff] >> 32 - rot);
|
||||
ki[ioff] = ko[ooff];
|
||||
ki[1 + ioff] = ko[1 + ooff];
|
||||
ki[2 + ioff] = ko[2 + ooff];
|
||||
ki[3 + ioff] = ko[3 + ooff];
|
||||
}
|
||||
|
||||
private static void decroldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
|
||||
{
|
||||
ko[2 + ooff] = (ki[ioff] << rot) | (ki[1 + ioff] >> 32 - rot);
|
||||
ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> 32 - rot);
|
||||
ko[ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> 32 - rot);
|
||||
ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[ioff] >> 32 - rot);
|
||||
ki[ioff] = ko[2 + ooff];
|
||||
ki[1 + ioff] = ko[3 + ooff];
|
||||
ki[2 + ioff] = ko[ooff];
|
||||
ki[3 + ioff] = ko[1 + ooff];
|
||||
}
|
||||
|
||||
private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
|
||||
{
|
||||
ko[ooff] = (ki[1 + ioff] << rot - 32) | (ki[2 + ioff] >> 64 - rot);
|
||||
ko[1 + ooff] = (ki[2 + ioff] << rot - 32) | (ki[3 + ioff] >> 64 - rot);
|
||||
ko[2 + ooff] = (ki[3 + ioff] << rot - 32) | (ki[ioff] >> 64 - rot);
|
||||
ko[3 + ooff] = (ki[ioff] << rot - 32) | (ki[1 + ioff] >> 64 - rot);
|
||||
ki[ioff] = ko[ooff];
|
||||
ki[1 + ioff] = ko[1 + ooff];
|
||||
ki[2 + ioff] = ko[2 + ooff];
|
||||
ki[3 + ioff] = ko[3 + ooff];
|
||||
}
|
||||
|
||||
private static void decroldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
|
||||
{
|
||||
ko[2 + ooff] = (ki[1 + ioff] << rot - 32) | (ki[2 + ioff] >> 64 - rot);
|
||||
ko[3 + ooff] = (ki[2 + ioff] << rot - 32) | (ki[3 + ioff] >> 64 - rot);
|
||||
ko[ooff] = (ki[3 + ioff] << rot - 32) | (ki[ioff] >> 64 - rot);
|
||||
ko[1 + ooff] = (ki[ioff] << rot - 32) | (ki[1 + ioff] >> 64 - rot);
|
||||
ki[ioff] = ko[2 + ooff];
|
||||
ki[1 + ioff] = ko[3 + ooff];
|
||||
ki[2 + ioff] = ko[ooff];
|
||||
ki[3 + ioff] = ko[1 + ooff];
|
||||
}
|
||||
|
||||
private static uint bytes2uint(byte[] src, int offset)
|
||||
{
|
||||
uint num = 0u;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
num = (num << 8) + src[i + offset];
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private static void uint2bytes(uint word, byte[] dst, int offset)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
dst[3 - i + offset] = (byte)word;
|
||||
word >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
private static void camelliaF2(uint[] s, uint[] skey, int keyoff)
|
||||
{
|
||||
uint num = s[0] ^ skey[keyoff];
|
||||
uint num2 = SBOX4_4404[(byte)num];
|
||||
num2 ^= SBOX3_3033[(byte)(num >> 8)];
|
||||
num2 ^= SBOX2_0222[(byte)(num >> 16)];
|
||||
num2 ^= SBOX1_1110[(byte)(num >> 24)];
|
||||
uint num3 = s[1] ^ skey[1 + keyoff];
|
||||
uint num4 = SBOX1_1110[(byte)num3];
|
||||
num4 ^= SBOX4_4404[(byte)(num3 >> 8)];
|
||||
num4 ^= SBOX3_3033[(byte)(num3 >> 16)];
|
||||
num4 ^= SBOX2_0222[(byte)(num3 >> 24)];
|
||||
uint[] array;
|
||||
(array = s)[2] = array[2] ^ (num2 ^ num4);
|
||||
(array = s)[3] = array[3] ^ (num2 ^ num4 ^ rightRotate(num2, 8));
|
||||
num = s[2] ^ skey[2 + keyoff];
|
||||
num2 = SBOX4_4404[(byte)num];
|
||||
num2 ^= SBOX3_3033[(byte)(num >> 8)];
|
||||
num2 ^= SBOX2_0222[(byte)(num >> 16)];
|
||||
num2 ^= SBOX1_1110[(byte)(num >> 24)];
|
||||
num3 = s[3] ^ skey[3 + keyoff];
|
||||
num4 = SBOX1_1110[(byte)num3];
|
||||
num4 ^= SBOX4_4404[(byte)(num3 >> 8)];
|
||||
num4 ^= SBOX3_3033[(byte)(num3 >> 16)];
|
||||
num4 ^= SBOX2_0222[(byte)(num3 >> 24)];
|
||||
(array = s)[0] = array[0] ^ (num2 ^ num4);
|
||||
(array = s)[1] = array[1] ^ (num2 ^ num4 ^ rightRotate(num2, 8));
|
||||
}
|
||||
|
||||
private static void camelliaFLs(uint[] s, uint[] fkey, int keyoff)
|
||||
{
|
||||
uint[] array;
|
||||
(array = s)[1] = array[1] ^ leftRotate(s[0] & fkey[keyoff], 1);
|
||||
(array = s)[0] = array[0] ^ (fkey[1 + keyoff] | s[1]);
|
||||
(array = s)[2] = array[2] ^ (fkey[3 + keyoff] | s[3]);
|
||||
(array = s)[3] = array[3] ^ leftRotate(fkey[2 + keyoff] & s[2], 1);
|
||||
}
|
||||
|
||||
private void setKey(bool forEncryption, byte[] key)
|
||||
{
|
||||
uint[] array = new uint[8];
|
||||
uint[] array2 = new uint[4];
|
||||
uint[] array3 = new uint[4];
|
||||
uint[] array4 = new uint[4];
|
||||
switch (key.Length)
|
||||
{
|
||||
case 16:
|
||||
_keyIs128 = true;
|
||||
array[0] = bytes2uint(key, 0);
|
||||
array[1] = bytes2uint(key, 4);
|
||||
array[2] = bytes2uint(key, 8);
|
||||
array[3] = bytes2uint(key, 12);
|
||||
array[4] = (array[5] = (array[6] = (array[7] = 0u)));
|
||||
break;
|
||||
case 24:
|
||||
array[0] = bytes2uint(key, 0);
|
||||
array[1] = bytes2uint(key, 4);
|
||||
array[2] = bytes2uint(key, 8);
|
||||
array[3] = bytes2uint(key, 12);
|
||||
array[4] = bytes2uint(key, 16);
|
||||
array[5] = bytes2uint(key, 20);
|
||||
array[6] = ~array[4];
|
||||
array[7] = ~array[5];
|
||||
_keyIs128 = false;
|
||||
break;
|
||||
case 32:
|
||||
array[0] = bytes2uint(key, 0);
|
||||
array[1] = bytes2uint(key, 4);
|
||||
array[2] = bytes2uint(key, 8);
|
||||
array[3] = bytes2uint(key, 12);
|
||||
array[4] = bytes2uint(key, 16);
|
||||
array[5] = bytes2uint(key, 20);
|
||||
array[6] = bytes2uint(key, 24);
|
||||
array[7] = bytes2uint(key, 28);
|
||||
_keyIs128 = false;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("key sizes are only 16/24/32 bytes.");
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
array2[i] = array[i] ^ array[i + 4];
|
||||
}
|
||||
camelliaF2(array2, SIGMA, 0);
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
uint[] array6;
|
||||
uint[] array5 = (array6 = array2);
|
||||
int num = j;
|
||||
nint num2 = num;
|
||||
array5[num] = array6[num2] ^ array[j];
|
||||
}
|
||||
camelliaF2(array2, SIGMA, 4);
|
||||
if (_keyIs128)
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
kw[0] = array[0];
|
||||
kw[1] = array[1];
|
||||
kw[2] = array[2];
|
||||
kw[3] = array[3];
|
||||
roldq(15, array, 0, subkey, 4);
|
||||
roldq(30, array, 0, subkey, 12);
|
||||
roldq(15, array, 0, array4, 0);
|
||||
subkey[18] = array4[2];
|
||||
subkey[19] = array4[3];
|
||||
roldq(17, array, 0, ke, 4);
|
||||
roldq(17, array, 0, subkey, 24);
|
||||
roldq(17, array, 0, subkey, 32);
|
||||
subkey[0] = array2[0];
|
||||
subkey[1] = array2[1];
|
||||
subkey[2] = array2[2];
|
||||
subkey[3] = array2[3];
|
||||
roldq(15, array2, 0, subkey, 8);
|
||||
roldq(15, array2, 0, ke, 0);
|
||||
roldq(15, array2, 0, array4, 0);
|
||||
subkey[16] = array4[0];
|
||||
subkey[17] = array4[1];
|
||||
roldq(15, array2, 0, subkey, 20);
|
||||
roldqo32(34, array2, 0, subkey, 28);
|
||||
roldq(17, array2, 0, kw, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
kw[4] = array[0];
|
||||
kw[5] = array[1];
|
||||
kw[6] = array[2];
|
||||
kw[7] = array[3];
|
||||
decroldq(15, array, 0, subkey, 28);
|
||||
decroldq(30, array, 0, subkey, 20);
|
||||
decroldq(15, array, 0, array4, 0);
|
||||
subkey[16] = array4[0];
|
||||
subkey[17] = array4[1];
|
||||
decroldq(17, array, 0, ke, 0);
|
||||
decroldq(17, array, 0, subkey, 8);
|
||||
decroldq(17, array, 0, subkey, 0);
|
||||
subkey[34] = array2[0];
|
||||
subkey[35] = array2[1];
|
||||
subkey[32] = array2[2];
|
||||
subkey[33] = array2[3];
|
||||
decroldq(15, array2, 0, subkey, 24);
|
||||
decroldq(15, array2, 0, ke, 4);
|
||||
decroldq(15, array2, 0, array4, 0);
|
||||
subkey[18] = array4[2];
|
||||
subkey[19] = array4[3];
|
||||
decroldq(15, array2, 0, subkey, 12);
|
||||
decroldqo32(34, array2, 0, subkey, 4);
|
||||
roldq(17, array2, 0, kw, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
array3[k] = array2[k] ^ array[k + 4];
|
||||
}
|
||||
camelliaF2(array3, SIGMA, 8);
|
||||
if (forEncryption)
|
||||
{
|
||||
kw[0] = array[0];
|
||||
kw[1] = array[1];
|
||||
kw[2] = array[2];
|
||||
kw[3] = array[3];
|
||||
roldqo32(45, array, 0, subkey, 16);
|
||||
roldq(15, array, 0, ke, 4);
|
||||
roldq(17, array, 0, subkey, 32);
|
||||
roldqo32(34, array, 0, subkey, 44);
|
||||
roldq(15, array, 4, subkey, 4);
|
||||
roldq(15, array, 4, ke, 0);
|
||||
roldq(30, array, 4, subkey, 24);
|
||||
roldqo32(34, array, 4, subkey, 36);
|
||||
roldq(15, array2, 0, subkey, 8);
|
||||
roldq(30, array2, 0, subkey, 20);
|
||||
ke[8] = array2[1];
|
||||
ke[9] = array2[2];
|
||||
ke[10] = array2[3];
|
||||
ke[11] = array2[0];
|
||||
roldqo32(49, array2, 0, subkey, 40);
|
||||
subkey[0] = array3[0];
|
||||
subkey[1] = array3[1];
|
||||
subkey[2] = array3[2];
|
||||
subkey[3] = array3[3];
|
||||
roldq(30, array3, 0, subkey, 12);
|
||||
roldq(30, array3, 0, subkey, 28);
|
||||
roldqo32(51, array3, 0, kw, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
kw[4] = array[0];
|
||||
kw[5] = array[1];
|
||||
kw[6] = array[2];
|
||||
kw[7] = array[3];
|
||||
decroldqo32(45, array, 0, subkey, 28);
|
||||
decroldq(15, array, 0, ke, 4);
|
||||
decroldq(17, array, 0, subkey, 12);
|
||||
decroldqo32(34, array, 0, subkey, 0);
|
||||
decroldq(15, array, 4, subkey, 40);
|
||||
decroldq(15, array, 4, ke, 8);
|
||||
decroldq(30, array, 4, subkey, 20);
|
||||
decroldqo32(34, array, 4, subkey, 8);
|
||||
decroldq(15, array2, 0, subkey, 36);
|
||||
decroldq(30, array2, 0, subkey, 24);
|
||||
ke[2] = array2[1];
|
||||
ke[3] = array2[2];
|
||||
ke[0] = array2[3];
|
||||
ke[1] = array2[0];
|
||||
decroldqo32(49, array2, 0, subkey, 4);
|
||||
subkey[46] = array3[0];
|
||||
subkey[47] = array3[1];
|
||||
subkey[44] = array3[2];
|
||||
subkey[45] = array3[3];
|
||||
decroldq(30, array3, 0, subkey, 32);
|
||||
decroldq(30, array3, 0, subkey, 16);
|
||||
roldqo32(51, array3, 0, kw, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private int processBlock128(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
uint[] array2;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
state[i] = bytes2uint(input, inOff + i * 4);
|
||||
uint[] array = (array2 = state);
|
||||
int num = i;
|
||||
nint num2 = num;
|
||||
array[num] = array2[num2] ^ kw[i];
|
||||
}
|
||||
camelliaF2(state, subkey, 0);
|
||||
camelliaF2(state, subkey, 4);
|
||||
camelliaF2(state, subkey, 8);
|
||||
camelliaFLs(state, ke, 0);
|
||||
camelliaF2(state, subkey, 12);
|
||||
camelliaF2(state, subkey, 16);
|
||||
camelliaF2(state, subkey, 20);
|
||||
camelliaFLs(state, ke, 4);
|
||||
camelliaF2(state, subkey, 24);
|
||||
camelliaF2(state, subkey, 28);
|
||||
camelliaF2(state, subkey, 32);
|
||||
(array2 = state)[2] = array2[2] ^ kw[4];
|
||||
(array2 = state)[3] = array2[3] ^ kw[5];
|
||||
(array2 = state)[0] = array2[0] ^ kw[6];
|
||||
(array2 = state)[1] = array2[1] ^ kw[7];
|
||||
uint2bytes(state[2], output, outOff);
|
||||
uint2bytes(state[3], output, outOff + 4);
|
||||
uint2bytes(state[0], output, outOff + 8);
|
||||
uint2bytes(state[1], output, outOff + 12);
|
||||
return 16;
|
||||
}
|
||||
|
||||
private int processBlock192or256(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
uint[] array2;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
state[i] = bytes2uint(input, inOff + i * 4);
|
||||
uint[] array = (array2 = state);
|
||||
int num = i;
|
||||
nint num2 = num;
|
||||
array[num] = array2[num2] ^ kw[i];
|
||||
}
|
||||
camelliaF2(state, subkey, 0);
|
||||
camelliaF2(state, subkey, 4);
|
||||
camelliaF2(state, subkey, 8);
|
||||
camelliaFLs(state, ke, 0);
|
||||
camelliaF2(state, subkey, 12);
|
||||
camelliaF2(state, subkey, 16);
|
||||
camelliaF2(state, subkey, 20);
|
||||
camelliaFLs(state, ke, 4);
|
||||
camelliaF2(state, subkey, 24);
|
||||
camelliaF2(state, subkey, 28);
|
||||
camelliaF2(state, subkey, 32);
|
||||
camelliaFLs(state, ke, 8);
|
||||
camelliaF2(state, subkey, 36);
|
||||
camelliaF2(state, subkey, 40);
|
||||
camelliaF2(state, subkey, 44);
|
||||
(array2 = state)[2] = array2[2] ^ kw[4];
|
||||
(array2 = state)[3] = array2[3] ^ kw[5];
|
||||
(array2 = state)[0] = array2[0] ^ kw[6];
|
||||
(array2 = state)[1] = array2[1] ^ kw[7];
|
||||
uint2bytes(state[2], output, outOff);
|
||||
uint2bytes(state[3], output, outOff + 4);
|
||||
uint2bytes(state[0], output, outOff + 8);
|
||||
uint2bytes(state[1], output, outOff + 12);
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter))
|
||||
{
|
||||
throw new ArgumentException("only simple KeyParameter expected.");
|
||||
}
|
||||
setKey(forEncryption, ((KeyParameter)parameters).GetKey());
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (!initialised)
|
||||
{
|
||||
throw new InvalidOperationException("Camellia engine not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 16, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 16, "output buffer too short");
|
||||
if (_keyIs128)
|
||||
{
|
||||
return processBlock128(input, inOff, output, outOff);
|
||||
}
|
||||
return processBlock192or256(input, inOff, output, outOff);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,491 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class CamelliaLightEngine : IBlockCipher
|
||||
{
|
||||
private const int BLOCK_SIZE = 16;
|
||||
|
||||
private bool initialised;
|
||||
|
||||
private bool _keyis128;
|
||||
|
||||
private uint[] subkey = new uint[96];
|
||||
|
||||
private uint[] kw = new uint[8];
|
||||
|
||||
private uint[] ke = new uint[12];
|
||||
|
||||
private uint[] state = new uint[4];
|
||||
|
||||
private static readonly uint[] SIGMA = new uint[12]
|
||||
{
|
||||
2694735487u, 1003262091u, 3061508184u, 1286239154u, 3337565999u, 3914302142u, 1426019237u, 4057165596u, 283453434u, 3731369245u,
|
||||
2958461122u, 3018244605u
|
||||
};
|
||||
|
||||
private static readonly byte[] SBOX1 = new byte[256]
|
||||
{
|
||||
112, 130, 44, 236, 179, 39, 192, 229, 228, 133,
|
||||
87, 53, 234, 12, 174, 65, 35, 239, 107, 147,
|
||||
69, 25, 165, 33, 237, 14, 79, 78, 29, 101,
|
||||
146, 189, 134, 184, 175, 143, 124, 235, 31, 206,
|
||||
62, 48, 220, 95, 94, 197, 11, 26, 166, 225,
|
||||
57, 202, 213, 71, 93, 61, 217, 1, 90, 214,
|
||||
81, 86, 108, 77, 139, 13, 154, 102, 251, 204,
|
||||
176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
|
||||
223, 76, 203, 194, 52, 126, 118, 5, 109, 183,
|
||||
169, 49, 209, 23, 4, 215, 20, 88, 58, 97,
|
||||
222, 27, 17, 28, 50, 15, 156, 22, 83, 24,
|
||||
242, 34, 254, 68, 207, 178, 195, 181, 122, 145,
|
||||
36, 8, 232, 168, 96, 252, 105, 80, 170, 208,
|
||||
160, 125, 161, 137, 98, 151, 84, 91, 30, 149,
|
||||
224, 255, 100, 210, 16, 196, 0, 72, 163, 247,
|
||||
117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
|
||||
135, 92, 131, 2, 205, 74, 144, 51, 115, 103,
|
||||
246, 243, 157, 127, 191, 226, 82, 155, 216, 38,
|
||||
200, 55, 198, 59, 129, 150, 111, 75, 19, 190,
|
||||
99, 46, 233, 121, 167, 140, 159, 110, 188, 142,
|
||||
41, 245, 249, 182, 47, 253, 180, 89, 120, 152,
|
||||
6, 106, 231, 70, 113, 186, 212, 37, 171, 66,
|
||||
136, 162, 141, 250, 114, 7, 185, 85, 248, 238,
|
||||
172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
|
||||
64, 40, 211, 123, 187, 201, 67, 193, 21, 227,
|
||||
173, 244, 119, 199, 128, 158
|
||||
};
|
||||
|
||||
public virtual string AlgorithmName => "Camellia";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
private static uint rightRotate(uint x, int s)
|
||||
{
|
||||
return (x >> s) + (x << 32 - s);
|
||||
}
|
||||
|
||||
private static uint leftRotate(uint x, int s)
|
||||
{
|
||||
return (x << s) + (x >> 32 - s);
|
||||
}
|
||||
|
||||
private static void roldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
|
||||
{
|
||||
ko[ooff] = (ki[ioff] << rot) | (ki[1 + ioff] >> 32 - rot);
|
||||
ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> 32 - rot);
|
||||
ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> 32 - rot);
|
||||
ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[ioff] >> 32 - rot);
|
||||
ki[ioff] = ko[ooff];
|
||||
ki[1 + ioff] = ko[1 + ooff];
|
||||
ki[2 + ioff] = ko[2 + ooff];
|
||||
ki[3 + ioff] = ko[3 + ooff];
|
||||
}
|
||||
|
||||
private static void decroldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
|
||||
{
|
||||
ko[2 + ooff] = (ki[ioff] << rot) | (ki[1 + ioff] >> 32 - rot);
|
||||
ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> 32 - rot);
|
||||
ko[ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> 32 - rot);
|
||||
ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[ioff] >> 32 - rot);
|
||||
ki[ioff] = ko[2 + ooff];
|
||||
ki[1 + ioff] = ko[3 + ooff];
|
||||
ki[2 + ioff] = ko[ooff];
|
||||
ki[3 + ioff] = ko[1 + ooff];
|
||||
}
|
||||
|
||||
private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
|
||||
{
|
||||
ko[ooff] = (ki[1 + ioff] << rot - 32) | (ki[2 + ioff] >> 64 - rot);
|
||||
ko[1 + ooff] = (ki[2 + ioff] << rot - 32) | (ki[3 + ioff] >> 64 - rot);
|
||||
ko[2 + ooff] = (ki[3 + ioff] << rot - 32) | (ki[ioff] >> 64 - rot);
|
||||
ko[3 + ooff] = (ki[ioff] << rot - 32) | (ki[1 + ioff] >> 64 - rot);
|
||||
ki[ioff] = ko[ooff];
|
||||
ki[1 + ioff] = ko[1 + ooff];
|
||||
ki[2 + ioff] = ko[2 + ooff];
|
||||
ki[3 + ioff] = ko[3 + ooff];
|
||||
}
|
||||
|
||||
private static void decroldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
|
||||
{
|
||||
ko[2 + ooff] = (ki[1 + ioff] << rot - 32) | (ki[2 + ioff] >> 64 - rot);
|
||||
ko[3 + ooff] = (ki[2 + ioff] << rot - 32) | (ki[3 + ioff] >> 64 - rot);
|
||||
ko[ooff] = (ki[3 + ioff] << rot - 32) | (ki[ioff] >> 64 - rot);
|
||||
ko[1 + ooff] = (ki[ioff] << rot - 32) | (ki[1 + ioff] >> 64 - rot);
|
||||
ki[ioff] = ko[2 + ooff];
|
||||
ki[1 + ioff] = ko[3 + ooff];
|
||||
ki[2 + ioff] = ko[ooff];
|
||||
ki[3 + ioff] = ko[1 + ooff];
|
||||
}
|
||||
|
||||
private static uint bytes2uint(byte[] src, int offset)
|
||||
{
|
||||
uint num = 0u;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
num = (num << 8) + src[i + offset];
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private static void uint2bytes(uint word, byte[] dst, int offset)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
dst[3 - i + offset] = (byte)word;
|
||||
word >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
private byte lRot8(byte v, int rot)
|
||||
{
|
||||
return (byte)((v << rot) | (v >>> 8 - rot));
|
||||
}
|
||||
|
||||
private uint sbox2(int x)
|
||||
{
|
||||
return lRot8(SBOX1[x], 1);
|
||||
}
|
||||
|
||||
private uint sbox3(int x)
|
||||
{
|
||||
return lRot8(SBOX1[x], 7);
|
||||
}
|
||||
|
||||
private uint sbox4(int x)
|
||||
{
|
||||
return SBOX1[lRot8((byte)x, 1)];
|
||||
}
|
||||
|
||||
private void camelliaF2(uint[] s, uint[] skey, int keyoff)
|
||||
{
|
||||
uint num = s[0] ^ skey[keyoff];
|
||||
uint num2 = sbox4((byte)num);
|
||||
num2 |= sbox3((byte)(num >> 8)) << 8;
|
||||
num2 |= sbox2((byte)(num >> 16)) << 16;
|
||||
num2 |= (uint)(SBOX1[(byte)(num >> 24)] << 24);
|
||||
uint num3 = s[1] ^ skey[1 + keyoff];
|
||||
uint num4 = SBOX1[(byte)num3];
|
||||
num4 |= sbox4((byte)(num3 >> 8)) << 8;
|
||||
num4 |= sbox3((byte)(num3 >> 16)) << 16;
|
||||
num4 |= sbox2((byte)(num3 >> 24)) << 24;
|
||||
num4 = leftRotate(num4, 8);
|
||||
num2 ^= num4;
|
||||
num4 = leftRotate(num4, 8) ^ num2;
|
||||
num2 = rightRotate(num2, 8) ^ num4;
|
||||
uint[] array;
|
||||
(array = s)[2] = array[2] ^ (leftRotate(num4, 16) ^ num2);
|
||||
(array = s)[3] = array[3] ^ leftRotate(num2, 8);
|
||||
num = s[2] ^ skey[2 + keyoff];
|
||||
num2 = sbox4((byte)num);
|
||||
num2 |= sbox3((byte)(num >> 8)) << 8;
|
||||
num2 |= sbox2((byte)(num >> 16)) << 16;
|
||||
num2 |= (uint)(SBOX1[(byte)(num >> 24)] << 24);
|
||||
num3 = s[3] ^ skey[3 + keyoff];
|
||||
num4 = SBOX1[(byte)num3];
|
||||
num4 |= sbox4((byte)(num3 >> 8)) << 8;
|
||||
num4 |= sbox3((byte)(num3 >> 16)) << 16;
|
||||
num4 |= sbox2((byte)(num3 >> 24)) << 24;
|
||||
num4 = leftRotate(num4, 8);
|
||||
num2 ^= num4;
|
||||
num4 = leftRotate(num4, 8) ^ num2;
|
||||
num2 = rightRotate(num2, 8) ^ num4;
|
||||
(array = s)[0] = array[0] ^ (leftRotate(num4, 16) ^ num2);
|
||||
(array = s)[1] = array[1] ^ leftRotate(num2, 8);
|
||||
}
|
||||
|
||||
private void camelliaFLs(uint[] s, uint[] fkey, int keyoff)
|
||||
{
|
||||
uint[] array;
|
||||
(array = s)[1] = array[1] ^ leftRotate(s[0] & fkey[keyoff], 1);
|
||||
(array = s)[0] = array[0] ^ (fkey[1 + keyoff] | s[1]);
|
||||
(array = s)[2] = array[2] ^ (fkey[3 + keyoff] | s[3]);
|
||||
(array = s)[3] = array[3] ^ leftRotate(fkey[2 + keyoff] & s[2], 1);
|
||||
}
|
||||
|
||||
private void setKey(bool forEncryption, byte[] key)
|
||||
{
|
||||
uint[] array = new uint[8];
|
||||
uint[] array2 = new uint[4];
|
||||
uint[] array3 = new uint[4];
|
||||
uint[] array4 = new uint[4];
|
||||
switch (key.Length)
|
||||
{
|
||||
case 16:
|
||||
_keyis128 = true;
|
||||
array[0] = bytes2uint(key, 0);
|
||||
array[1] = bytes2uint(key, 4);
|
||||
array[2] = bytes2uint(key, 8);
|
||||
array[3] = bytes2uint(key, 12);
|
||||
array[4] = (array[5] = (array[6] = (array[7] = 0u)));
|
||||
break;
|
||||
case 24:
|
||||
array[0] = bytes2uint(key, 0);
|
||||
array[1] = bytes2uint(key, 4);
|
||||
array[2] = bytes2uint(key, 8);
|
||||
array[3] = bytes2uint(key, 12);
|
||||
array[4] = bytes2uint(key, 16);
|
||||
array[5] = bytes2uint(key, 20);
|
||||
array[6] = ~array[4];
|
||||
array[7] = ~array[5];
|
||||
_keyis128 = false;
|
||||
break;
|
||||
case 32:
|
||||
array[0] = bytes2uint(key, 0);
|
||||
array[1] = bytes2uint(key, 4);
|
||||
array[2] = bytes2uint(key, 8);
|
||||
array[3] = bytes2uint(key, 12);
|
||||
array[4] = bytes2uint(key, 16);
|
||||
array[5] = bytes2uint(key, 20);
|
||||
array[6] = bytes2uint(key, 24);
|
||||
array[7] = bytes2uint(key, 28);
|
||||
_keyis128 = false;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("key sizes are only 16/24/32 bytes.");
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
array2[i] = array[i] ^ array[i + 4];
|
||||
}
|
||||
camelliaF2(array2, SIGMA, 0);
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
uint[] array6;
|
||||
uint[] array5 = (array6 = array2);
|
||||
int num = j;
|
||||
nint num2 = num;
|
||||
array5[num] = array6[num2] ^ array[j];
|
||||
}
|
||||
camelliaF2(array2, SIGMA, 4);
|
||||
if (_keyis128)
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
kw[0] = array[0];
|
||||
kw[1] = array[1];
|
||||
kw[2] = array[2];
|
||||
kw[3] = array[3];
|
||||
roldq(15, array, 0, subkey, 4);
|
||||
roldq(30, array, 0, subkey, 12);
|
||||
roldq(15, array, 0, array4, 0);
|
||||
subkey[18] = array4[2];
|
||||
subkey[19] = array4[3];
|
||||
roldq(17, array, 0, ke, 4);
|
||||
roldq(17, array, 0, subkey, 24);
|
||||
roldq(17, array, 0, subkey, 32);
|
||||
subkey[0] = array2[0];
|
||||
subkey[1] = array2[1];
|
||||
subkey[2] = array2[2];
|
||||
subkey[3] = array2[3];
|
||||
roldq(15, array2, 0, subkey, 8);
|
||||
roldq(15, array2, 0, ke, 0);
|
||||
roldq(15, array2, 0, array4, 0);
|
||||
subkey[16] = array4[0];
|
||||
subkey[17] = array4[1];
|
||||
roldq(15, array2, 0, subkey, 20);
|
||||
roldqo32(34, array2, 0, subkey, 28);
|
||||
roldq(17, array2, 0, kw, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
kw[4] = array[0];
|
||||
kw[5] = array[1];
|
||||
kw[6] = array[2];
|
||||
kw[7] = array[3];
|
||||
decroldq(15, array, 0, subkey, 28);
|
||||
decroldq(30, array, 0, subkey, 20);
|
||||
decroldq(15, array, 0, array4, 0);
|
||||
subkey[16] = array4[0];
|
||||
subkey[17] = array4[1];
|
||||
decroldq(17, array, 0, ke, 0);
|
||||
decroldq(17, array, 0, subkey, 8);
|
||||
decroldq(17, array, 0, subkey, 0);
|
||||
subkey[34] = array2[0];
|
||||
subkey[35] = array2[1];
|
||||
subkey[32] = array2[2];
|
||||
subkey[33] = array2[3];
|
||||
decroldq(15, array2, 0, subkey, 24);
|
||||
decroldq(15, array2, 0, ke, 4);
|
||||
decroldq(15, array2, 0, array4, 0);
|
||||
subkey[18] = array4[2];
|
||||
subkey[19] = array4[3];
|
||||
decroldq(15, array2, 0, subkey, 12);
|
||||
decroldqo32(34, array2, 0, subkey, 4);
|
||||
roldq(17, array2, 0, kw, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
array3[k] = array2[k] ^ array[k + 4];
|
||||
}
|
||||
camelliaF2(array3, SIGMA, 8);
|
||||
if (forEncryption)
|
||||
{
|
||||
kw[0] = array[0];
|
||||
kw[1] = array[1];
|
||||
kw[2] = array[2];
|
||||
kw[3] = array[3];
|
||||
roldqo32(45, array, 0, subkey, 16);
|
||||
roldq(15, array, 0, ke, 4);
|
||||
roldq(17, array, 0, subkey, 32);
|
||||
roldqo32(34, array, 0, subkey, 44);
|
||||
roldq(15, array, 4, subkey, 4);
|
||||
roldq(15, array, 4, ke, 0);
|
||||
roldq(30, array, 4, subkey, 24);
|
||||
roldqo32(34, array, 4, subkey, 36);
|
||||
roldq(15, array2, 0, subkey, 8);
|
||||
roldq(30, array2, 0, subkey, 20);
|
||||
ke[8] = array2[1];
|
||||
ke[9] = array2[2];
|
||||
ke[10] = array2[3];
|
||||
ke[11] = array2[0];
|
||||
roldqo32(49, array2, 0, subkey, 40);
|
||||
subkey[0] = array3[0];
|
||||
subkey[1] = array3[1];
|
||||
subkey[2] = array3[2];
|
||||
subkey[3] = array3[3];
|
||||
roldq(30, array3, 0, subkey, 12);
|
||||
roldq(30, array3, 0, subkey, 28);
|
||||
roldqo32(51, array3, 0, kw, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
kw[4] = array[0];
|
||||
kw[5] = array[1];
|
||||
kw[6] = array[2];
|
||||
kw[7] = array[3];
|
||||
decroldqo32(45, array, 0, subkey, 28);
|
||||
decroldq(15, array, 0, ke, 4);
|
||||
decroldq(17, array, 0, subkey, 12);
|
||||
decroldqo32(34, array, 0, subkey, 0);
|
||||
decroldq(15, array, 4, subkey, 40);
|
||||
decroldq(15, array, 4, ke, 8);
|
||||
decroldq(30, array, 4, subkey, 20);
|
||||
decroldqo32(34, array, 4, subkey, 8);
|
||||
decroldq(15, array2, 0, subkey, 36);
|
||||
decroldq(30, array2, 0, subkey, 24);
|
||||
ke[2] = array2[1];
|
||||
ke[3] = array2[2];
|
||||
ke[0] = array2[3];
|
||||
ke[1] = array2[0];
|
||||
decroldqo32(49, array2, 0, subkey, 4);
|
||||
subkey[46] = array3[0];
|
||||
subkey[47] = array3[1];
|
||||
subkey[44] = array3[2];
|
||||
subkey[45] = array3[3];
|
||||
decroldq(30, array3, 0, subkey, 32);
|
||||
decroldq(30, array3, 0, subkey, 16);
|
||||
roldqo32(51, array3, 0, kw, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private int processBlock128(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
uint[] array2;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
state[i] = bytes2uint(input, inOff + i * 4);
|
||||
uint[] array = (array2 = state);
|
||||
int num = i;
|
||||
nint num2 = num;
|
||||
array[num] = array2[num2] ^ kw[i];
|
||||
}
|
||||
camelliaF2(state, subkey, 0);
|
||||
camelliaF2(state, subkey, 4);
|
||||
camelliaF2(state, subkey, 8);
|
||||
camelliaFLs(state, ke, 0);
|
||||
camelliaF2(state, subkey, 12);
|
||||
camelliaF2(state, subkey, 16);
|
||||
camelliaF2(state, subkey, 20);
|
||||
camelliaFLs(state, ke, 4);
|
||||
camelliaF2(state, subkey, 24);
|
||||
camelliaF2(state, subkey, 28);
|
||||
camelliaF2(state, subkey, 32);
|
||||
(array2 = state)[2] = array2[2] ^ kw[4];
|
||||
(array2 = state)[3] = array2[3] ^ kw[5];
|
||||
(array2 = state)[0] = array2[0] ^ kw[6];
|
||||
(array2 = state)[1] = array2[1] ^ kw[7];
|
||||
uint2bytes(state[2], output, outOff);
|
||||
uint2bytes(state[3], output, outOff + 4);
|
||||
uint2bytes(state[0], output, outOff + 8);
|
||||
uint2bytes(state[1], output, outOff + 12);
|
||||
return 16;
|
||||
}
|
||||
|
||||
private int processBlock192or256(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
uint[] array2;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
state[i] = bytes2uint(input, inOff + i * 4);
|
||||
uint[] array = (array2 = state);
|
||||
int num = i;
|
||||
nint num2 = num;
|
||||
array[num] = array2[num2] ^ kw[i];
|
||||
}
|
||||
camelliaF2(state, subkey, 0);
|
||||
camelliaF2(state, subkey, 4);
|
||||
camelliaF2(state, subkey, 8);
|
||||
camelliaFLs(state, ke, 0);
|
||||
camelliaF2(state, subkey, 12);
|
||||
camelliaF2(state, subkey, 16);
|
||||
camelliaF2(state, subkey, 20);
|
||||
camelliaFLs(state, ke, 4);
|
||||
camelliaF2(state, subkey, 24);
|
||||
camelliaF2(state, subkey, 28);
|
||||
camelliaF2(state, subkey, 32);
|
||||
camelliaFLs(state, ke, 8);
|
||||
camelliaF2(state, subkey, 36);
|
||||
camelliaF2(state, subkey, 40);
|
||||
camelliaF2(state, subkey, 44);
|
||||
(array2 = state)[2] = array2[2] ^ kw[4];
|
||||
(array2 = state)[3] = array2[3] ^ kw[5];
|
||||
(array2 = state)[0] = array2[0] ^ kw[6];
|
||||
(array2 = state)[1] = array2[1] ^ kw[7];
|
||||
uint2bytes(state[2], output, outOff);
|
||||
uint2bytes(state[3], output, outOff + 4);
|
||||
uint2bytes(state[0], output, outOff + 8);
|
||||
uint2bytes(state[1], output, outOff + 12);
|
||||
return 16;
|
||||
}
|
||||
|
||||
public CamelliaLightEngine()
|
||||
{
|
||||
initialised = false;
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter))
|
||||
{
|
||||
throw new ArgumentException("only simple KeyParameter expected.");
|
||||
}
|
||||
setKey(forEncryption, ((KeyParameter)parameters).GetKey());
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (!initialised)
|
||||
{
|
||||
throw new InvalidOperationException("Camellia engine not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 16, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 16, "output buffer too short");
|
||||
if (_keyis128)
|
||||
{
|
||||
return processBlock128(input, inOff, output, outOff);
|
||||
}
|
||||
return processBlock192or256(input, inOff, output, outOff);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class CamelliaWrapEngine : Rfc3394WrapEngine
|
||||
{
|
||||
public CamelliaWrapEngine()
|
||||
: base(new CamelliaEngine())
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,585 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class Cast5Engine : IBlockCipher
|
||||
{
|
||||
private const int BLOCK_SIZE = 8;
|
||||
|
||||
private static readonly uint[] S1 = new uint[256]
|
||||
{
|
||||
821772500u, 2678128395u, 1810681135u, 1059425402u, 505495343u, 2617265619u, 1610868032u, 3483355465u, 3218386727u, 2294005173u,
|
||||
3791863952u, 2563806837u, 1852023008u, 365126098u, 3269944861u, 584384398u, 677919599u, 3229601881u, 4280515016u, 2002735330u,
|
||||
1136869587u, 3744433750u, 2289869850u, 2731719981u, 2714362070u, 879511577u, 1639411079u, 575934255u, 717107937u, 2857637483u,
|
||||
576097850u, 2731753936u, 1725645000u, 2810460463u, 5111599u, 767152862u, 2543075244u, 1251459544u, 1383482551u, 3052681127u,
|
||||
3089939183u, 3612463449u, 1878520045u, 1510570527u, 2189125840u, 2431448366u, 582008916u, 3163445557u, 1265446783u, 1354458274u,
|
||||
3529918736u, 3202711853u, 3073581712u, 3912963487u, 3029263377u, 1275016285u, 4249207360u, 2905708351u, 3304509486u, 1442611557u,
|
||||
3585198765u, 2712415662u, 2731849581u, 3248163920u, 2283946226u, 208555832u, 2766454743u, 1331405426u, 1447828783u, 3315356441u,
|
||||
3108627284u, 2957404670u, 2981538698u, 3339933917u, 1669711173u, 286233437u, 1465092821u, 1782121619u, 3862771680u, 710211251u,
|
||||
980974943u, 1651941557u, 430374111u, 2051154026u, 704238805u, 4128970897u, 3144820574u, 2857402727u, 948965521u, 3333752299u,
|
||||
2227686284u, 718756367u, 2269778983u, 2731643755u, 718440111u, 2857816721u, 3616097120u, 1113355533u, 2478022182u, 410092745u,
|
||||
1811985197u, 1944238868u, 2696854588u, 1415722873u, 1682284203u, 1060277122u, 1998114690u, 1503841958u, 82706478u, 2315155686u,
|
||||
1068173648u, 845149890u, 2167947013u, 1768146376u, 1993038550u, 3566826697u, 3390574031u, 940016341u, 3355073782u, 2328040721u,
|
||||
904371731u, 1205506512u, 4094660742u, 2816623006u, 825647681u, 85914773u, 2857843460u, 1249926541u, 1417871568u, 3287612u,
|
||||
3211054559u, 3126306446u, 1975924523u, 1353700161u, 2814456437u, 2438597621u, 1800716203u, 722146342u, 2873936343u, 1151126914u,
|
||||
4160483941u, 2877670899u, 458611604u, 2866078500u, 3483680063u, 770352098u, 2652916994u, 3367839148u, 3940505011u, 3585973912u,
|
||||
3809620402u, 718646636u, 2504206814u, 2914927912u, 3631288169u, 2857486607u, 2860018678u, 575749918u, 2857478043u, 718488780u,
|
||||
2069512688u, 3548183469u, 453416197u, 1106044049u, 3032691430u, 52586708u, 3378514636u, 3459808877u, 3211506028u, 1785789304u,
|
||||
218356169u, 3571399134u, 3759170522u, 1194783844u, 1523787992u, 3007827094u, 1975193539u, 2555452411u, 1341901877u, 3045838698u,
|
||||
3776907964u, 3217423946u, 2802510864u, 2889438986u, 1057244207u, 1636348243u, 3761863214u, 1462225785u, 2632663439u, 481089165u,
|
||||
718503062u, 24497053u, 3332243209u, 3344655856u, 3655024856u, 3960371065u, 1195698900u, 2971415156u, 3710176158u, 2115785917u,
|
||||
4027663609u, 3525578417u, 2524296189u, 2745972565u, 3564906415u, 1372086093u, 1452307862u, 2780501478u, 1476592880u, 3389271281u,
|
||||
18495466u, 2378148571u, 901398090u, 891748256u, 3279637769u, 3157290713u, 2560960102u, 1447622437u, 4284372637u, 216884176u,
|
||||
2086908623u, 1879786977u, 3588903153u, 2242455666u, 2938092967u, 3559082096u, 2810645491u, 758861177u, 1121993112u, 215018983u,
|
||||
642190776u, 4169236812u, 1196255959u, 2081185372u, 3508738393u, 941322904u, 4124243163u, 2877523539u, 1848581667u, 2205260958u,
|
||||
3180453958u, 2589345134u, 3694731276u, 550028657u, 2519456284u, 3789985535u, 2973870856u, 2093648313u, 443148163u, 46942275u,
|
||||
2734146937u, 1117713533u, 1115362972u, 1523183689u, 3717140224u, 1551984063u
|
||||
};
|
||||
|
||||
private static readonly uint[] S2 = new uint[256]
|
||||
{
|
||||
522195092u, 4010518363u, 1776537470u, 960447360u, 4267822970u, 4005896314u, 1435016340u, 1929119313u, 2913464185u, 1310552629u,
|
||||
3579470798u, 3724818106u, 2579771631u, 1594623892u, 417127293u, 2715217907u, 2696228731u, 1508390405u, 3994398868u, 3925858569u,
|
||||
3695444102u, 4019471449u, 3129199795u, 3770928635u, 3520741761u, 990456497u, 4187484609u, 2783367035u, 21106139u, 3840405339u,
|
||||
631373633u, 3783325702u, 532942976u, 396095098u, 3548038825u, 4267192484u, 2564721535u, 2011709262u, 2039648873u, 620404603u,
|
||||
3776170075u, 2898526339u, 3612357925u, 4159332703u, 1645490516u, 223693667u, 1567101217u, 3362177881u, 1029951347u, 3470931136u,
|
||||
3570957959u, 1550265121u, 119497089u, 972513919u, 907948164u, 3840628539u, 1613718692u, 3594177948u, 465323573u, 2659255085u,
|
||||
654439692u, 2575596212u, 2699288441u, 3127702412u, 277098644u, 624404830u, 4100943870u, 2717858591u, 546110314u, 2403699828u,
|
||||
3655377447u, 1321679412u, 4236791657u, 1045293279u, 4010672264u, 895050893u, 2319792268u, 494945126u, 1914543101u, 2777056443u,
|
||||
3894764339u, 2219737618u, 311263384u, 4275257268u, 3458730721u, 669096869u, 3584475730u, 3835122877u, 3319158237u, 3949359204u,
|
||||
2005142349u, 2713102337u, 2228954793u, 3769984788u, 569394103u, 3855636576u, 1425027204u, 108000370u, 2736431443u, 3671869269u,
|
||||
3043122623u, 1750473702u, 2211081108u, 762237499u, 3972989403u, 2798899386u, 3061857628u, 2943854345u, 867476300u, 964413654u,
|
||||
1591880597u, 1594774276u, 2179821409u, 552026980u, 3026064248u, 3726140315u, 2283577634u, 3110545105u, 2152310760u, 582474363u,
|
||||
1582640421u, 1383256631u, 2043843868u, 3322775884u, 1217180674u, 463797851u, 2763038571u, 480777679u, 2718707717u, 2289164131u,
|
||||
3118346187u, 214354409u, 200212307u, 3810608407u, 3025414197u, 2674075964u, 3997296425u, 1847405948u, 1342460550u, 510035443u,
|
||||
4080271814u, 815934613u, 833030224u, 1620250387u, 1945732119u, 2703661145u, 3966000196u, 1388869545u, 3456054182u, 2687178561u,
|
||||
2092620194u, 562037615u, 1356438536u, 3409922145u, 3261847397u, 1688467115u, 2150901366u, 631725691u, 3840332284u, 549916902u,
|
||||
3455104640u, 394546491u, 837744717u, 2114462948u, 751520235u, 2221554606u, 2415360136u, 3999097078u, 2063029875u, 803036379u,
|
||||
2702586305u, 821456707u, 3019566164u, 360699898u, 4018502092u, 3511869016u, 3677355358u, 2402471449u, 812317050u, 49299192u,
|
||||
2570164949u, 3259169295u, 2816732080u, 3331213574u, 3101303564u, 2156015656u, 3705598920u, 3546263921u, 143268808u, 3200304480u,
|
||||
1638124008u, 3165189453u, 3341807610u, 578956953u, 2193977524u, 3638120073u, 2333881532u, 807278310u, 658237817u, 2969561766u,
|
||||
1641658566u, 11683945u, 3086995007u, 148645947u, 1138423386u, 4158756760u, 1981396783u, 2401016740u, 3699783584u, 380097457u,
|
||||
2680394679u, 2803068651u, 3334260286u, 441530178u, 4016580796u, 1375954390u, 761952171u, 891809099u, 2183123478u, 157052462u,
|
||||
3683840763u, 1592404427u, 341349109u, 2438483839u, 1417898363u, 644327628u, 2233032776u, 2353769706u, 2201510100u, 220455161u,
|
||||
1815641738u, 182899273u, 2995019788u, 3627381533u, 3702638151u, 2890684138u, 1052606899u, 588164016u, 1681439879u, 4038439418u,
|
||||
2405343923u, 4229449282u, 167996282u, 1336969661u, 1688053129u, 2739224926u, 1543734051u, 1046297529u, 1138201970u, 2121126012u,
|
||||
115334942u, 1819067631u, 1902159161u, 1941945968u, 2206692869u, 1159982321u
|
||||
};
|
||||
|
||||
private static readonly uint[] S3 = new uint[256]
|
||||
{
|
||||
2381300288u, 637164959u, 3952098751u, 3893414151u, 1197506559u, 916448331u, 2350892612u, 2932787856u, 3199334847u, 4009478890u,
|
||||
3905886544u, 1373570990u, 2450425862u, 4037870920u, 3778841987u, 2456817877u, 286293407u, 124026297u, 3001279700u, 1028597854u,
|
||||
3115296800u, 4208886496u, 2691114635u, 2188540206u, 1430237888u, 1218109995u, 3572471700u, 308166588u, 570424558u, 2187009021u,
|
||||
2455094765u, 307733056u, 1310360322u, 3135275007u, 1384269543u, 2388071438u, 863238079u, 2359263624u, 2801553128u, 3380786597u,
|
||||
2831162807u, 1470087780u, 1728663345u, 4072488799u, 1090516929u, 532123132u, 2389430977u, 1132193179u, 2578464191u, 3051079243u,
|
||||
1670234342u, 1434557849u, 2711078940u, 1241591150u, 3314043432u, 3435360113u, 3091448339u, 1812415473u, 2198440252u, 267246943u,
|
||||
796911696u, 3619716990u, 38830015u, 1526438404u, 2806502096u, 374413614u, 2943401790u, 1489179520u, 1603809326u, 1920779204u,
|
||||
168801282u, 260042626u, 2358705581u, 1563175598u, 2397674057u, 1356499128u, 2217211040u, 514611088u, 2037363785u, 2186468373u,
|
||||
4022173083u, 2792511869u, 2913485016u, 1173701892u, 4200428547u, 3896427269u, 1334932762u, 2455136706u, 602925377u, 2835607854u,
|
||||
1613172210u, 41346230u, 2499634548u, 2457437618u, 2188827595u, 41386358u, 4172255629u, 1313404830u, 2405527007u, 3801973774u,
|
||||
2217704835u, 873260488u, 2528884354u, 2478092616u, 4012915883u, 2555359016u, 2006953883u, 2463913485u, 575479328u, 2218240648u,
|
||||
2099895446u, 660001756u, 2341502190u, 3038761536u, 3888151779u, 3848713377u, 3286851934u, 1022894237u, 1620365795u, 3449594689u,
|
||||
1551255054u, 15374395u, 3570825345u, 4249311020u, 4151111129u, 3181912732u, 310226346u, 1133119310u, 530038928u, 136043402u,
|
||||
2476768958u, 3107506709u, 2544909567u, 1036173560u, 2367337196u, 1681395281u, 1758231547u, 3641649032u, 306774401u, 1575354324u,
|
||||
3716085866u, 1990386196u, 3114533736u, 2455606671u, 1262092282u, 3124342505u, 2768229131u, 4210529083u, 1833535011u, 423410938u,
|
||||
660763973u, 2187129978u, 1639812000u, 3508421329u, 3467445492u, 310289298u, 272797111u, 2188552562u, 2456863912u, 310240523u,
|
||||
677093832u, 1013118031u, 901835429u, 3892695601u, 1116285435u, 3036471170u, 1337354835u, 243122523u, 520626091u, 277223598u,
|
||||
4244441197u, 4194248841u, 1766575121u, 594173102u, 316590669u, 742362309u, 3536858622u, 4176435350u, 3838792410u, 2501204839u,
|
||||
1229605004u, 3115755532u, 1552908988u, 2312334149u, 979407927u, 3959474601u, 1148277331u, 176638793u, 3614686272u, 2083809052u,
|
||||
40992502u, 1340822838u, 2731552767u, 3535757508u, 3560899520u, 1354035053u, 122129617u, 7215240u, 2732932949u, 3118912700u,
|
||||
2718203926u, 2539075635u, 3609230695u, 3725561661u, 1928887091u, 2882293555u, 1988674909u, 2063640240u, 2491088897u, 1459647954u,
|
||||
4189817080u, 2302804382u, 1113892351u, 2237858528u, 1927010603u, 4002880361u, 1856122846u, 1594404395u, 2944033133u, 3855189863u,
|
||||
3474975698u, 1643104450u, 4054590833u, 3431086530u, 1730235576u, 2984608721u, 3084664418u, 2131803598u, 4178205752u, 267404349u,
|
||||
1617849798u, 1616132681u, 1462223176u, 736725533u, 2327058232u, 551665188u, 2945899023u, 1749386277u, 2575514597u, 1611482493u,
|
||||
674206544u, 2201269090u, 3642560800u, 728599968u, 1680547377u, 2620414464u, 1388111496u, 453204106u, 4156223445u, 1094905244u,
|
||||
2754698257u, 2201108165u, 3757000246u, 2704524545u, 3922940700u, 3996465027u
|
||||
};
|
||||
|
||||
private static readonly uint[] S4 = new uint[256]
|
||||
{
|
||||
2645754912u, 532081118u, 2814278639u, 3530793624u, 1246723035u, 1689095255u, 2236679235u, 4194438865u, 2116582143u, 3859789411u,
|
||||
157234593u, 2045505824u, 4245003587u, 1687664561u, 4083425123u, 605965023u, 672431967u, 1336064205u, 3376611392u, 214114848u,
|
||||
4258466608u, 3232053071u, 489488601u, 605322005u, 3998028058u, 264917351u, 1912574028u, 756637694u, 436560991u, 202637054u,
|
||||
135989450u, 85393697u, 2152923392u, 3896401662u, 2895836408u, 2145855233u, 3535335007u, 115294817u, 3147733898u, 1922296357u,
|
||||
3464822751u, 4117858305u, 1037454084u, 2725193275u, 2127856640u, 1417604070u, 1148013728u, 1827919605u, 642362335u, 2929772533u,
|
||||
909348033u, 1346338451u, 3547799649u, 297154785u, 1917849091u, 4161712827u, 2883604526u, 3968694238u, 1469521537u, 3780077382u,
|
||||
3375584256u, 1763717519u, 136166297u, 4290970789u, 1295325189u, 2134727907u, 2798151366u, 1566297257u, 3672928234u, 2677174161u,
|
||||
2672173615u, 965822077u, 2780786062u, 289653839u, 1133871874u, 3491843819u, 35685304u, 1068898316u, 418943774u, 672553190u,
|
||||
642281022u, 2346158704u, 1954014401u, 3037126780u, 4079815205u, 2030668546u, 3840588673u, 672283427u, 1776201016u, 359975446u,
|
||||
3750173538u, 555499703u, 2769985273u, 1324923u, 69110472u, 152125443u, 3176785106u, 3822147285u, 1340634837u, 798073664u,
|
||||
1434183902u, 15393959u, 216384236u, 1303690150u, 3881221631u, 3711134124u, 3960975413u, 106373927u, 2578434224u, 1455997841u,
|
||||
1801814300u, 1578393881u, 1854262133u, 3188178946u, 3258078583u, 2302670060u, 1539295533u, 3505142565u, 3078625975u, 2372746020u,
|
||||
549938159u, 3278284284u, 2620926080u, 181285381u, 2865321098u, 3970029511u, 68876850u, 488006234u, 1728155692u, 2608167508u,
|
||||
836007927u, 2435231793u, 919367643u, 3339422534u, 3655756360u, 1457871481u, 40520939u, 1380155135u, 797931188u, 234455205u,
|
||||
2255801827u, 3990488299u, 397000196u, 739833055u, 3077865373u, 2871719860u, 4022553888u, 772369276u, 390177364u, 3853951029u,
|
||||
557662966u, 740064294u, 1640166671u, 1699928825u, 3535942136u, 622006121u, 3625353122u, 68743880u, 1742502u, 219489963u,
|
||||
1664179233u, 1577743084u, 1236991741u, 410585305u, 2366487942u, 823226535u, 1050371084u, 3426619607u, 3586839478u, 212779912u,
|
||||
4147118561u, 1819446015u, 1911218849u, 530248558u, 3486241071u, 3252585495u, 2886188651u, 3410272728u, 2342195030u, 20547779u,
|
||||
2982490058u, 3032363469u, 3631753222u, 312714466u, 1870521650u, 1493008054u, 3491686656u, 615382978u, 4103671749u, 2534517445u,
|
||||
1932181u, 2196105170u, 278426614u, 6369430u, 3274544417u, 2913018367u, 697336853u, 2143000447u, 2946413531u, 701099306u,
|
||||
1558357093u, 2805003052u, 3500818408u, 2321334417u, 3567135975u, 216290473u, 3591032198u, 23009561u, 1996984579u, 3735042806u,
|
||||
2024298078u, 3739440863u, 569400510u, 2339758983u, 3016033873u, 3097871343u, 3639523026u, 3844324983u, 3256173865u, 795471839u,
|
||||
2951117563u, 4101031090u, 4091603803u, 3603732598u, 971261452u, 534414648u, 428311343u, 3389027175u, 2844869880u, 694888862u,
|
||||
1227866773u, 2456207019u, 3043454569u, 2614353370u, 3749578031u, 3676663836u, 459166190u, 4132644070u, 1794958188u, 51825668u,
|
||||
2252611902u, 3084671440u, 2036672799u, 3436641603u, 1099053433u, 2469121526u, 3059204941u, 1323291266u, 2061838604u, 1018778475u,
|
||||
2233344254u, 2553501054u, 334295216u, 3556750194u, 1065731521u, 183467730u
|
||||
};
|
||||
|
||||
private static readonly uint[] S5 = new uint[256]
|
||||
{
|
||||
2127105028u, 745436345u, 2601412319u, 2788391185u, 3093987327u, 500390133u, 1155374404u, 389092991u, 150729210u, 3891597772u,
|
||||
3523549952u, 1935325696u, 716645080u, 946045387u, 2901812282u, 1774124410u, 3869435775u, 4039581901u, 3293136918u, 3438657920u,
|
||||
948246080u, 363898952u, 3867875531u, 1286266623u, 1598556673u, 68334250u, 630723836u, 1104211938u, 1312863373u, 613332731u,
|
||||
2377784574u, 1101634306u, 441780740u, 3129959883u, 1917973735u, 2510624549u, 3238456535u, 2544211978u, 3308894634u, 1299840618u,
|
||||
4076074851u, 1756332096u, 3977027158u, 297047435u, 3790297736u, 2265573040u, 3621810518u, 1311375015u, 1667687725u, 47300608u,
|
||||
3299642885u, 2474112369u, 201668394u, 1468347890u, 576830978u, 3594690761u, 3742605952u, 1958042578u, 1747032512u, 3558991340u,
|
||||
1408974056u, 3366841779u, 682131401u, 1033214337u, 1545599232u, 4265137049u, 206503691u, 103024618u, 2855227313u, 1337551222u,
|
||||
2428998917u, 2963842932u, 4015366655u, 3852247746u, 2796956967u, 3865723491u, 3747938335u, 247794022u, 3755824572u, 702416469u,
|
||||
2434691994u, 397379957u, 851939612u, 2314769512u, 218229120u, 1380406772u, 62274761u, 214451378u, 3170103466u, 2276210409u,
|
||||
3845813286u, 28563499u, 446592073u, 1693330814u, 3453727194u, 29968656u, 3093872512u, 220656637u, 2470637031u, 77972100u,
|
||||
1667708854u, 1358280214u, 4064765667u, 2395616961u, 325977563u, 4277240721u, 4220025399u, 3605526484u, 3355147721u, 811859167u,
|
||||
3069544926u, 3962126810u, 652502677u, 3075892249u, 4132761541u, 3498924215u, 1217549313u, 3250244479u, 3858715919u, 3053989961u,
|
||||
1538642152u, 2279026266u, 2875879137u, 574252750u, 3324769229u, 2651358713u, 1758150215u, 141295887u, 2719868960u, 3515574750u,
|
||||
4093007735u, 4194485238u, 1082055363u, 3417560400u, 395511885u, 2966884026u, 179534037u, 3646028556u, 3738688086u, 1092926436u,
|
||||
2496269142u, 257381841u, 3772900718u, 1636087230u, 1477059743u, 2499234752u, 3811018894u, 2675660129u, 3285975680u, 90732309u,
|
||||
1684827095u, 1150307763u, 1723134115u, 3237045386u, 1769919919u, 1240018934u, 815675215u, 750138730u, 2239792499u, 1234303040u,
|
||||
1995484674u, 138143821u, 675421338u, 1145607174u, 1936608440u, 3238603024u, 2345230278u, 2105974004u, 323969391u, 779555213u,
|
||||
3004902369u, 2861610098u, 1017501463u, 2098600890u, 2628620304u, 2940611490u, 2682542546u, 1171473753u, 3656571411u, 3687208071u,
|
||||
4091869518u, 393037935u, 159126506u, 1662887367u, 1147106178u, 391545844u, 3452332695u, 1891500680u, 3016609650u, 1851642611u,
|
||||
546529401u, 1167818917u, 3194020571u, 2848076033u, 3953471836u, 575554290u, 475796850u, 4134673196u, 450035699u, 2351251534u,
|
||||
844027695u, 1080539133u, 86184846u, 1554234488u, 3692025454u, 1972511363u, 2018339607u, 1491841390u, 1141460869u, 1061690759u,
|
||||
4244549243u, 2008416118u, 2351104703u, 2868147542u, 1598468138u, 722020353u, 1027143159u, 212344630u, 1387219594u, 1725294528u,
|
||||
3745187956u, 2500153616u, 458938280u, 4129215917u, 1828119673u, 544571780u, 3503225445u, 2297937496u, 1241802790u, 267843827u,
|
||||
2694610800u, 1397140384u, 1558801448u, 3782667683u, 1806446719u, 929573330u, 2234912681u, 400817706u, 616011623u, 4121520928u,
|
||||
3603768725u, 1761550015u, 1968522284u, 4053731006u, 4192232858u, 4005120285u, 872482584u, 3140537016u, 3894607381u, 2287405443u,
|
||||
1963876937u, 3663887957u, 1584857000u, 2975024454u, 1833426440u, 4025083860u
|
||||
};
|
||||
|
||||
private static readonly uint[] S6 = new uint[256]
|
||||
{
|
||||
4143615901u, 749497569u, 1285769319u, 3795025788u, 2514159847u, 23610292u, 3974978748u, 844452780u, 3214870880u, 3751928557u,
|
||||
2213566365u, 1676510905u, 448177848u, 3730751033u, 4086298418u, 2307502392u, 871450977u, 3222878141u, 4110862042u, 3831651966u,
|
||||
2735270553u, 1310974780u, 2043402188u, 1218528103u, 2736035353u, 4274605013u, 2702448458u, 3936360550u, 2693061421u, 162023535u,
|
||||
2827510090u, 687910808u, 23484817u, 3784910947u, 3371371616u, 779677500u, 3503626546u, 3473927188u, 4157212626u, 3500679282u,
|
||||
4248902014u, 2466621104u, 3899384794u, 1958663117u, 925738300u, 1283408968u, 3669349440u, 1840910019u, 137959847u, 2679828185u,
|
||||
1239142320u, 1315376211u, 1547541505u, 1690155329u, 739140458u, 3128809933u, 3933172616u, 3876308834u, 905091803u, 1548541325u,
|
||||
4040461708u, 3095483362u, 144808038u, 451078856u, 676114313u, 2861728291u, 2469707347u, 993665471u, 373509091u, 2599041286u,
|
||||
4025009006u, 4170239449u, 2149739950u, 3275793571u, 3749616649u, 2794760199u, 1534877388u, 572371878u, 2590613551u, 1753320020u,
|
||||
3467782511u, 1405125690u, 4270405205u, 633333386u, 3026356924u, 3475123903u, 632057672u, 2846462855u, 1404951397u, 3882875879u,
|
||||
3915906424u, 195638627u, 2385783745u, 3902872553u, 1233155085u, 3355999740u, 2380578713u, 2702246304u, 2144565621u, 3663341248u,
|
||||
3894384975u, 2502479241u, 4248018925u, 3094885567u, 1594115437u, 572884632u, 3385116731u, 767645374u, 1331858858u, 1475698373u,
|
||||
3793881790u, 3532746431u, 1321687957u, 619889600u, 1121017241u, 3440213920u, 2070816767u, 2833025776u, 1933951238u, 4095615791u,
|
||||
890643334u, 3874130214u, 859025556u, 360630002u, 925594799u, 1764062180u, 3920222280u, 4078305929u, 979562269u, 2810700344u,
|
||||
4087740022u, 1949714515u, 546639971u, 1165388173u, 3069891591u, 1495988560u, 922170659u, 1291546247u, 2107952832u, 1813327274u,
|
||||
3406010024u, 3306028637u, 4241950635u, 153207855u, 2313154747u, 1608695416u, 1150242611u, 1967526857u, 721801357u, 1220138373u,
|
||||
3691287617u, 3356069787u, 2112743302u, 3281662835u, 1111556101u, 1778980689u, 250857638u, 2298507990u, 673216130u, 2846488510u,
|
||||
3207751581u, 3562756981u, 3008625920u, 3417367384u, 2198807050u, 529510932u, 3547516680u, 3426503187u, 2364944742u, 102533054u,
|
||||
2294910856u, 1617093527u, 1204784762u, 3066581635u, 1019391227u, 1069574518u, 1317995090u, 1691889997u, 3661132003u, 510022745u,
|
||||
3238594800u, 1362108837u, 1817929911u, 2184153760u, 805817662u, 1953603311u, 3699844737u, 120799444u, 2118332377u, 207536705u,
|
||||
2282301548u, 4120041617u, 145305846u, 2508124933u, 3086745533u, 3261524335u, 1877257368u, 2977164480u, 3160454186u, 2503252186u,
|
||||
4221677074u, 759945014u, 254147243u, 2767453419u, 3801518371u, 629083197u, 2471014217u, 907280572u, 3900796746u, 940896768u,
|
||||
2751021123u, 2625262786u, 3161476951u, 3661752313u, 3260732218u, 1425318020u, 2977912069u, 1496677566u, 3988592072u, 2140652971u,
|
||||
3126511541u, 3069632175u, 977771578u, 1392695845u, 1698528874u, 1411812681u, 1369733098u, 1343739227u, 3620887944u, 1142123638u,
|
||||
67414216u, 3102056737u, 3088749194u, 1626167401u, 2546293654u, 3941374235u, 697522451u, 33404913u, 143560186u, 2595682037u,
|
||||
994885535u, 1247667115u, 3859094837u, 2699155541u, 3547024625u, 4114935275u, 2968073508u, 3199963069u, 2732024527u, 1237921620u,
|
||||
951448369u, 1898488916u, 1211705605u, 2790989240u, 2233243581u, 3598044975u
|
||||
};
|
||||
|
||||
private static readonly uint[] S7 = new uint[256]
|
||||
{
|
||||
2246066201u, 858518887u, 1714274303u, 3485882003u, 713916271u, 2879113490u, 3730835617u, 539548191u, 36158695u, 1298409750u,
|
||||
419087104u, 1358007170u, 749914897u, 2989680476u, 1261868530u, 2995193822u, 2690628854u, 3443622377u, 3780124940u, 3796824509u,
|
||||
2976433025u, 4259637129u, 1551479000u, 512490819u, 1296650241u, 951993153u, 2436689437u, 2460458047u, 144139966u, 3136204276u,
|
||||
310820559u, 3068840729u, 643875328u, 1969602020u, 1680088954u, 2185813161u, 3283332454u, 672358534u, 198762408u, 896343282u,
|
||||
276269502u, 3014846926u, 84060815u, 197145886u, 376173866u, 3943890818u, 3813173521u, 3545068822u, 1316698879u, 1598252827u,
|
||||
2633424951u, 1233235075u, 859989710u, 2358460855u, 3503838400u, 3409603720u, 1203513385u, 1193654839u, 2792018475u, 2060853022u,
|
||||
207403770u, 1144516871u, 3068631394u, 1121114134u, 177607304u, 3785736302u, 326409831u, 1929119770u, 2983279095u, 4183308101u,
|
||||
3474579288u, 3200513878u, 3228482096u, 119610148u, 1170376745u, 3378393471u, 3163473169u, 951863017u, 3337026068u, 3135789130u,
|
||||
2907618374u, 1183797387u, 2015970143u, 4045674555u, 2182986399u, 2952138740u, 3928772205u, 384012900u, 2454997643u, 10178499u,
|
||||
2879818989u, 2596892536u, 111523738u, 2995089006u, 451689641u, 3196290696u, 235406569u, 1441906262u, 3890558523u, 3013735005u,
|
||||
4158569349u, 1644036924u, 376726067u, 1006849064u, 3664579700u, 2041234796u, 1021632941u, 1374734338u, 2566452058u, 371631263u,
|
||||
4007144233u, 490221539u, 206551450u, 3140638584u, 1053219195u, 1853335209u, 3412429660u, 3562156231u, 735133835u, 1623211703u,
|
||||
3104214392u, 2738312436u, 4096837757u, 3366392578u, 3110964274u, 3956598718u, 3196820781u, 2038037254u, 3877786376u, 2339753847u,
|
||||
300912036u, 3766732888u, 2372630639u, 1516443558u, 4200396704u, 1574567987u, 4069441456u, 4122592016u, 2699739776u, 146372218u,
|
||||
2748961456u, 2043888151u, 35287437u, 2596680554u, 655490400u, 1132482787u, 110692520u, 1031794116u, 2188192751u, 1324057718u,
|
||||
1217253157u, 919197030u, 686247489u, 3261139658u, 1028237775u, 3135486431u, 3059715558u, 2460921700u, 986174950u, 2661811465u,
|
||||
4062904701u, 2752986992u, 3709736643u, 367056889u, 1353824391u, 731860949u, 1650113154u, 1778481506u, 784341916u, 357075625u,
|
||||
3608602432u, 1074092588u, 2480052770u, 3811426202u, 92751289u, 877911070u, 3600361838u, 1231880047u, 480201094u, 3756190983u,
|
||||
3094495953u, 434011822u, 87971354u, 363687820u, 1717726236u, 1901380172u, 3926403882u, 2481662265u, 400339184u, 1490350766u,
|
||||
2661455099u, 1389319756u, 2558787174u, 784598401u, 1983468483u, 30828846u, 3550527752u, 2716276238u, 3841122214u, 1765724805u,
|
||||
1955612312u, 1277890269u, 1333098070u, 1564029816u, 2704417615u, 1026694237u, 3287671188u, 1260819201u, 3349086767u, 1016692350u,
|
||||
1582273796u, 1073413053u, 1995943182u, 694588404u, 1025494639u, 3323872702u, 3551898420u, 4146854327u, 453260480u, 1316140391u,
|
||||
1435673405u, 3038941953u, 3486689407u, 1622062951u, 403978347u, 817677117u, 950059133u, 4246079218u, 3278066075u, 1486738320u,
|
||||
1417279718u, 481875527u, 2549965225u, 3933690356u, 760697757u, 1452955855u, 3897451437u, 1177426808u, 1702951038u, 4085348628u,
|
||||
2447005172u, 1084371187u, 3516436277u, 3068336338u, 1073369276u, 1027665953u, 3284188590u, 1230553676u, 1368340146u, 2226246512u,
|
||||
267243139u, 2274220762u, 4070734279u, 2497715176u, 2423353163u, 2504755875u
|
||||
};
|
||||
|
||||
private static readonly uint[] S8 = new uint[256]
|
||||
{
|
||||
3793104909u, 3151888380u, 2817252029u, 895778965u, 2005530807u, 3871412763u, 237245952u, 86829237u, 296341424u, 3851759377u,
|
||||
3974600970u, 2475086196u, 709006108u, 1994621201u, 2972577594u, 937287164u, 3734691505u, 168608556u, 3189338153u, 2225080640u,
|
||||
3139713551u, 3033610191u, 3025041904u, 77524477u, 185966941u, 1208824168u, 2344345178u, 1721625922u, 3354191921u, 1066374631u,
|
||||
1927223579u, 1971335949u, 2483503697u, 1551748602u, 2881383779u, 2856329572u, 3003241482u, 48746954u, 1398218158u, 2050065058u,
|
||||
313056748u, 4255789917u, 393167848u, 1912293076u, 940740642u, 3465845460u, 3091687853u, 2522601570u, 2197016661u, 1727764327u,
|
||||
364383054u, 492521376u, 1291706479u, 3264136376u, 1474851438u, 1685747964u, 2575719748u, 1619776915u, 1814040067u, 970743798u,
|
||||
1561002147u, 2925768690u, 2123093554u, 1880132620u, 3151188041u, 697884420u, 2550985770u, 2607674513u, 2659114323u, 110200136u,
|
||||
1489731079u, 997519150u, 1378877361u, 3527870668u, 478029773u, 2766872923u, 1022481122u, 431258168u, 1112503832u, 897933369u,
|
||||
2635587303u, 669726182u, 3383752315u, 918222264u, 163866573u, 3246985393u, 3776823163u, 114105080u, 1903216136u, 761148244u,
|
||||
3571337562u, 1690750982u, 3166750252u, 1037045171u, 1888456500u, 2010454850u, 642736655u, 616092351u, 365016990u, 1185228132u,
|
||||
4174898510u, 1043824992u, 2023083429u, 2241598885u, 3863320456u, 3279669087u, 3674716684u, 108438443u, 2132974366u, 830746235u,
|
||||
606445527u, 4173263986u, 2204105912u, 1844756978u, 2532684181u, 4245352700u, 2969441100u, 3796921661u, 1335562986u, 4061524517u,
|
||||
2720232303u, 2679424040u, 634407289u, 885462008u, 3294724487u, 3933892248u, 2094100220u, 339117932u, 4048830727u, 3202280980u,
|
||||
1458155303u, 2689246273u, 1022871705u, 2464987878u, 3714515309u, 353796843u, 2822958815u, 4256850100u, 4052777845u, 551748367u,
|
||||
618185374u, 3778635579u, 4020649912u, 1904685140u, 3069366075u, 2670879810u, 3407193292u, 2954511620u, 4058283405u, 2219449317u,
|
||||
3135758300u, 1120655984u, 3447565834u, 1474845562u, 3577699062u, 550456716u, 3466908712u, 2043752612u, 881257467u, 869518812u,
|
||||
2005220179u, 938474677u, 3305539448u, 3850417126u, 1315485940u, 3318264702u, 226533026u, 965733244u, 321539988u, 1136104718u,
|
||||
804158748u, 573969341u, 3708209826u, 937399083u, 3290727049u, 2901666755u, 1461057207u, 4013193437u, 4066861423u, 3242773476u,
|
||||
2421326174u, 1581322155u, 3028952165u, 786071460u, 3900391652u, 3918438532u, 1485433313u, 4023619836u, 3708277595u, 3678951060u,
|
||||
953673138u, 1467089153u, 1930354364u, 1533292819u, 2492563023u, 1346121658u, 1685000834u, 1965281866u, 3765933717u, 4190206607u,
|
||||
2052792609u, 3515332758u, 690371149u, 3125873887u, 2180283551u, 2903598061u, 3933952357u, 436236910u, 289419410u, 14314871u,
|
||||
1242357089u, 2904507907u, 1616633776u, 2666382180u, 585885352u, 3471299210u, 2699507360u, 1432659641u, 277164553u, 3354103607u,
|
||||
770115018u, 2303809295u, 3741942315u, 3177781868u, 2853364978u, 2269453327u, 3774259834u, 987383833u, 1290892879u, 225909803u,
|
||||
1741533526u, 890078084u, 1496906255u, 1111072499u, 916028167u, 243534141u, 1252605537u, 2204162171u, 531204876u, 290011180u,
|
||||
3916834213u, 102027703u, 237315147u, 209093447u, 1486785922u, 220223953u, 2758195998u, 4175039106u, 82940208u, 3127791296u,
|
||||
2569425252u, 518464269u, 1353887104u, 3941492737u, 2377294467u, 3935040926u
|
||||
};
|
||||
|
||||
internal static readonly int MAX_ROUNDS = 16;
|
||||
|
||||
internal static readonly int RED_ROUNDS = 12;
|
||||
|
||||
private int[] _Kr = new int[17];
|
||||
|
||||
private uint[] _Km = new uint[17];
|
||||
|
||||
private bool _encrypting;
|
||||
|
||||
private byte[] _workingKey;
|
||||
|
||||
private int _rounds = MAX_ROUNDS;
|
||||
|
||||
public virtual string AlgorithmName => "CAST5";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter))
|
||||
{
|
||||
throw new ArgumentException("Invalid parameter passed to " + AlgorithmName + " init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
_encrypting = forEncryption;
|
||||
_workingKey = ((KeyParameter)parameters).GetKey();
|
||||
SetKey(_workingKey);
|
||||
}
|
||||
|
||||
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
int blockSize = GetBlockSize();
|
||||
if (_workingKey == null)
|
||||
{
|
||||
throw new InvalidOperationException(AlgorithmName + " not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, blockSize, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, blockSize, "output buffer too short");
|
||||
if (_encrypting)
|
||||
{
|
||||
return EncryptBlock(input, inOff, output, outOff);
|
||||
}
|
||||
return DecryptBlock(input, inOff, output, outOff);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
internal virtual void SetKey(byte[] key)
|
||||
{
|
||||
if (key.Length < 11)
|
||||
{
|
||||
_rounds = RED_ROUNDS;
|
||||
}
|
||||
int[] array = new int[16];
|
||||
int[] array2 = new int[16];
|
||||
for (int i = 0; i < key.Length; i++)
|
||||
{
|
||||
array2[i] = key[i] & 0xFF;
|
||||
}
|
||||
uint num = IntsTo32bits(array2, 0);
|
||||
uint num2 = IntsTo32bits(array2, 4);
|
||||
uint num3 = IntsTo32bits(array2, 8);
|
||||
uint num4 = IntsTo32bits(array2, 12);
|
||||
uint inData = num ^ S5[array2[13]] ^ S6[array2[15]] ^ S7[array2[12]] ^ S8[array2[14]] ^ S7[array2[8]];
|
||||
Bits32ToInts(inData, array, 0);
|
||||
uint inData2 = num3 ^ S5[array[0]] ^ S6[array[2]] ^ S7[array[1]] ^ S8[array[3]] ^ S8[array2[10]];
|
||||
Bits32ToInts(inData2, array, 4);
|
||||
uint inData3 = num4 ^ S5[array[7]] ^ S6[array[6]] ^ S7[array[5]] ^ S8[array[4]] ^ S5[array2[9]];
|
||||
Bits32ToInts(inData3, array, 8);
|
||||
uint inData4 = num2 ^ S5[array[10]] ^ S6[array[9]] ^ S7[array[11]] ^ S8[array[8]] ^ S6[array2[11]];
|
||||
Bits32ToInts(inData4, array, 12);
|
||||
_Km[1] = S5[array[8]] ^ S6[array[9]] ^ S7[array[7]] ^ S8[array[6]] ^ S5[array[2]];
|
||||
_Km[2] = S5[array[10]] ^ S6[array[11]] ^ S7[array[5]] ^ S8[array[4]] ^ S6[array[6]];
|
||||
_Km[3] = S5[array[12]] ^ S6[array[13]] ^ S7[array[3]] ^ S8[array[2]] ^ S7[array[9]];
|
||||
_Km[4] = S5[array[14]] ^ S6[array[15]] ^ S7[array[1]] ^ S8[array[0]] ^ S8[array[12]];
|
||||
inData = IntsTo32bits(array, 0);
|
||||
inData2 = IntsTo32bits(array, 4);
|
||||
inData3 = IntsTo32bits(array, 8);
|
||||
inData4 = IntsTo32bits(array, 12);
|
||||
num = inData3 ^ S5[array[5]] ^ S6[array[7]] ^ S7[array[4]] ^ S8[array[6]] ^ S7[array[0]];
|
||||
Bits32ToInts(num, array2, 0);
|
||||
num2 = inData ^ S5[array2[0]] ^ S6[array2[2]] ^ S7[array2[1]] ^ S8[array2[3]] ^ S8[array[2]];
|
||||
Bits32ToInts(num2, array2, 4);
|
||||
num3 = inData2 ^ S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S5[array[1]];
|
||||
Bits32ToInts(num3, array2, 8);
|
||||
num4 = inData4 ^ S5[array2[10]] ^ S6[array2[9]] ^ S7[array2[11]] ^ S8[array2[8]] ^ S6[array[3]];
|
||||
Bits32ToInts(num4, array2, 12);
|
||||
_Km[5] = S5[array2[3]] ^ S6[array2[2]] ^ S7[array2[12]] ^ S8[array2[13]] ^ S5[array2[8]];
|
||||
_Km[6] = S5[array2[1]] ^ S6[array2[0]] ^ S7[array2[14]] ^ S8[array2[15]] ^ S6[array2[13]];
|
||||
_Km[7] = S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[8]] ^ S8[array2[9]] ^ S7[array2[3]];
|
||||
_Km[8] = S5[array2[5]] ^ S6[array2[4]] ^ S7[array2[10]] ^ S8[array2[11]] ^ S8[array2[7]];
|
||||
num = IntsTo32bits(array2, 0);
|
||||
num2 = IntsTo32bits(array2, 4);
|
||||
num3 = IntsTo32bits(array2, 8);
|
||||
num4 = IntsTo32bits(array2, 12);
|
||||
inData = num ^ S5[array2[13]] ^ S6[array2[15]] ^ S7[array2[12]] ^ S8[array2[14]] ^ S7[array2[8]];
|
||||
Bits32ToInts(inData, array, 0);
|
||||
inData2 = num3 ^ S5[array[0]] ^ S6[array[2]] ^ S7[array[1]] ^ S8[array[3]] ^ S8[array2[10]];
|
||||
Bits32ToInts(inData2, array, 4);
|
||||
inData3 = num4 ^ S5[array[7]] ^ S6[array[6]] ^ S7[array[5]] ^ S8[array[4]] ^ S5[array2[9]];
|
||||
Bits32ToInts(inData3, array, 8);
|
||||
inData4 = num2 ^ S5[array[10]] ^ S6[array[9]] ^ S7[array[11]] ^ S8[array[8]] ^ S6[array2[11]];
|
||||
Bits32ToInts(inData4, array, 12);
|
||||
_Km[9] = S5[array[3]] ^ S6[array[2]] ^ S7[array[12]] ^ S8[array[13]] ^ S5[array[9]];
|
||||
_Km[10] = S5[array[1]] ^ S6[array[0]] ^ S7[array[14]] ^ S8[array[15]] ^ S6[array[12]];
|
||||
_Km[11] = S5[array[7]] ^ S6[array[6]] ^ S7[array[8]] ^ S8[array[9]] ^ S7[array[2]];
|
||||
_Km[12] = S5[array[5]] ^ S6[array[4]] ^ S7[array[10]] ^ S8[array[11]] ^ S8[array[6]];
|
||||
inData = IntsTo32bits(array, 0);
|
||||
inData2 = IntsTo32bits(array, 4);
|
||||
inData3 = IntsTo32bits(array, 8);
|
||||
inData4 = IntsTo32bits(array, 12);
|
||||
num = inData3 ^ S5[array[5]] ^ S6[array[7]] ^ S7[array[4]] ^ S8[array[6]] ^ S7[array[0]];
|
||||
Bits32ToInts(num, array2, 0);
|
||||
num2 = inData ^ S5[array2[0]] ^ S6[array2[2]] ^ S7[array2[1]] ^ S8[array2[3]] ^ S8[array[2]];
|
||||
Bits32ToInts(num2, array2, 4);
|
||||
num3 = inData2 ^ S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S5[array[1]];
|
||||
Bits32ToInts(num3, array2, 8);
|
||||
num4 = inData4 ^ S5[array2[10]] ^ S6[array2[9]] ^ S7[array2[11]] ^ S8[array2[8]] ^ S6[array[3]];
|
||||
Bits32ToInts(num4, array2, 12);
|
||||
_Km[13] = S5[array2[8]] ^ S6[array2[9]] ^ S7[array2[7]] ^ S8[array2[6]] ^ S5[array2[3]];
|
||||
_Km[14] = S5[array2[10]] ^ S6[array2[11]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S6[array2[7]];
|
||||
_Km[15] = S5[array2[12]] ^ S6[array2[13]] ^ S7[array2[3]] ^ S8[array2[2]] ^ S7[array2[8]];
|
||||
_Km[16] = S5[array2[14]] ^ S6[array2[15]] ^ S7[array2[1]] ^ S8[array2[0]] ^ S8[array2[13]];
|
||||
num = IntsTo32bits(array2, 0);
|
||||
num2 = IntsTo32bits(array2, 4);
|
||||
num3 = IntsTo32bits(array2, 8);
|
||||
num4 = IntsTo32bits(array2, 12);
|
||||
inData = num ^ S5[array2[13]] ^ S6[array2[15]] ^ S7[array2[12]] ^ S8[array2[14]] ^ S7[array2[8]];
|
||||
Bits32ToInts(inData, array, 0);
|
||||
inData2 = num3 ^ S5[array[0]] ^ S6[array[2]] ^ S7[array[1]] ^ S8[array[3]] ^ S8[array2[10]];
|
||||
Bits32ToInts(inData2, array, 4);
|
||||
inData3 = num4 ^ S5[array[7]] ^ S6[array[6]] ^ S7[array[5]] ^ S8[array[4]] ^ S5[array2[9]];
|
||||
Bits32ToInts(inData3, array, 8);
|
||||
inData4 = num2 ^ S5[array[10]] ^ S6[array[9]] ^ S7[array[11]] ^ S8[array[8]] ^ S6[array2[11]];
|
||||
Bits32ToInts(inData4, array, 12);
|
||||
_Kr[1] = (int)((S5[array[8]] ^ S6[array[9]] ^ S7[array[7]] ^ S8[array[6]] ^ S5[array[2]]) & 0x1F);
|
||||
_Kr[2] = (int)((S5[array[10]] ^ S6[array[11]] ^ S7[array[5]] ^ S8[array[4]] ^ S6[array[6]]) & 0x1F);
|
||||
_Kr[3] = (int)((S5[array[12]] ^ S6[array[13]] ^ S7[array[3]] ^ S8[array[2]] ^ S7[array[9]]) & 0x1F);
|
||||
_Kr[4] = (int)((S5[array[14]] ^ S6[array[15]] ^ S7[array[1]] ^ S8[array[0]] ^ S8[array[12]]) & 0x1F);
|
||||
inData = IntsTo32bits(array, 0);
|
||||
inData2 = IntsTo32bits(array, 4);
|
||||
inData3 = IntsTo32bits(array, 8);
|
||||
inData4 = IntsTo32bits(array, 12);
|
||||
num = inData3 ^ S5[array[5]] ^ S6[array[7]] ^ S7[array[4]] ^ S8[array[6]] ^ S7[array[0]];
|
||||
Bits32ToInts(num, array2, 0);
|
||||
num2 = inData ^ S5[array2[0]] ^ S6[array2[2]] ^ S7[array2[1]] ^ S8[array2[3]] ^ S8[array[2]];
|
||||
Bits32ToInts(num2, array2, 4);
|
||||
num3 = inData2 ^ S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S5[array[1]];
|
||||
Bits32ToInts(num3, array2, 8);
|
||||
num4 = inData4 ^ S5[array2[10]] ^ S6[array2[9]] ^ S7[array2[11]] ^ S8[array2[8]] ^ S6[array[3]];
|
||||
Bits32ToInts(num4, array2, 12);
|
||||
_Kr[5] = (int)((S5[array2[3]] ^ S6[array2[2]] ^ S7[array2[12]] ^ S8[array2[13]] ^ S5[array2[8]]) & 0x1F);
|
||||
_Kr[6] = (int)((S5[array2[1]] ^ S6[array2[0]] ^ S7[array2[14]] ^ S8[array2[15]] ^ S6[array2[13]]) & 0x1F);
|
||||
_Kr[7] = (int)((S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[8]] ^ S8[array2[9]] ^ S7[array2[3]]) & 0x1F);
|
||||
_Kr[8] = (int)((S5[array2[5]] ^ S6[array2[4]] ^ S7[array2[10]] ^ S8[array2[11]] ^ S8[array2[7]]) & 0x1F);
|
||||
num = IntsTo32bits(array2, 0);
|
||||
num2 = IntsTo32bits(array2, 4);
|
||||
num3 = IntsTo32bits(array2, 8);
|
||||
num4 = IntsTo32bits(array2, 12);
|
||||
inData = num ^ S5[array2[13]] ^ S6[array2[15]] ^ S7[array2[12]] ^ S8[array2[14]] ^ S7[array2[8]];
|
||||
Bits32ToInts(inData, array, 0);
|
||||
inData2 = num3 ^ S5[array[0]] ^ S6[array[2]] ^ S7[array[1]] ^ S8[array[3]] ^ S8[array2[10]];
|
||||
Bits32ToInts(inData2, array, 4);
|
||||
inData3 = num4 ^ S5[array[7]] ^ S6[array[6]] ^ S7[array[5]] ^ S8[array[4]] ^ S5[array2[9]];
|
||||
Bits32ToInts(inData3, array, 8);
|
||||
inData4 = num2 ^ S5[array[10]] ^ S6[array[9]] ^ S7[array[11]] ^ S8[array[8]] ^ S6[array2[11]];
|
||||
Bits32ToInts(inData4, array, 12);
|
||||
_Kr[9] = (int)((S5[array[3]] ^ S6[array[2]] ^ S7[array[12]] ^ S8[array[13]] ^ S5[array[9]]) & 0x1F);
|
||||
_Kr[10] = (int)((S5[array[1]] ^ S6[array[0]] ^ S7[array[14]] ^ S8[array[15]] ^ S6[array[12]]) & 0x1F);
|
||||
_Kr[11] = (int)((S5[array[7]] ^ S6[array[6]] ^ S7[array[8]] ^ S8[array[9]] ^ S7[array[2]]) & 0x1F);
|
||||
_Kr[12] = (int)((S5[array[5]] ^ S6[array[4]] ^ S7[array[10]] ^ S8[array[11]] ^ S8[array[6]]) & 0x1F);
|
||||
inData = IntsTo32bits(array, 0);
|
||||
inData2 = IntsTo32bits(array, 4);
|
||||
inData3 = IntsTo32bits(array, 8);
|
||||
inData4 = IntsTo32bits(array, 12);
|
||||
num = inData3 ^ S5[array[5]] ^ S6[array[7]] ^ S7[array[4]] ^ S8[array[6]] ^ S7[array[0]];
|
||||
Bits32ToInts(num, array2, 0);
|
||||
num2 = inData ^ S5[array2[0]] ^ S6[array2[2]] ^ S7[array2[1]] ^ S8[array2[3]] ^ S8[array[2]];
|
||||
Bits32ToInts(num2, array2, 4);
|
||||
num3 = inData2 ^ S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S5[array[1]];
|
||||
Bits32ToInts(num3, array2, 8);
|
||||
num4 = inData4 ^ S5[array2[10]] ^ S6[array2[9]] ^ S7[array2[11]] ^ S8[array2[8]] ^ S6[array[3]];
|
||||
Bits32ToInts(num4, array2, 12);
|
||||
_Kr[13] = (int)((S5[array2[8]] ^ S6[array2[9]] ^ S7[array2[7]] ^ S8[array2[6]] ^ S5[array2[3]]) & 0x1F);
|
||||
_Kr[14] = (int)((S5[array2[10]] ^ S6[array2[11]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S6[array2[7]]) & 0x1F);
|
||||
_Kr[15] = (int)((S5[array2[12]] ^ S6[array2[13]] ^ S7[array2[3]] ^ S8[array2[2]] ^ S7[array2[8]]) & 0x1F);
|
||||
_Kr[16] = (int)((S5[array2[14]] ^ S6[array2[15]] ^ S7[array2[1]] ^ S8[array2[0]] ^ S8[array2[13]]) & 0x1F);
|
||||
}
|
||||
|
||||
internal virtual int EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
|
||||
{
|
||||
uint l = Pack.BE_To_UInt32(src, srcIndex);
|
||||
uint r = Pack.BE_To_UInt32(src, srcIndex + 4);
|
||||
uint[] array = new uint[2];
|
||||
CAST_Encipher(l, r, array);
|
||||
Pack.UInt32_To_BE(array[0], dst, dstIndex);
|
||||
Pack.UInt32_To_BE(array[1], dst, dstIndex + 4);
|
||||
return 8;
|
||||
}
|
||||
|
||||
internal virtual int DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
|
||||
{
|
||||
uint l = Pack.BE_To_UInt32(src, srcIndex);
|
||||
uint r = Pack.BE_To_UInt32(src, srcIndex + 4);
|
||||
uint[] array = new uint[2];
|
||||
CAST_Decipher(l, r, array);
|
||||
Pack.UInt32_To_BE(array[0], dst, dstIndex);
|
||||
Pack.UInt32_To_BE(array[1], dst, dstIndex + 4);
|
||||
return 8;
|
||||
}
|
||||
|
||||
internal static uint F1(uint D, uint Kmi, int Kri)
|
||||
{
|
||||
uint num = Kmi + D;
|
||||
num = (num << Kri) | (num >> 32 - Kri);
|
||||
return (S1[(num >> 24) & 0xFF] ^ S2[(num >> 16) & 0xFF]) - S3[(num >> 8) & 0xFF] + S4[num & 0xFF];
|
||||
}
|
||||
|
||||
internal static uint F2(uint D, uint Kmi, int Kri)
|
||||
{
|
||||
uint num = Kmi ^ D;
|
||||
num = (num << Kri) | (num >> 32 - Kri);
|
||||
return (S1[(num >> 24) & 0xFF] - S2[(num >> 16) & 0xFF] + S3[(num >> 8) & 0xFF]) ^ S4[num & 0xFF];
|
||||
}
|
||||
|
||||
internal static uint F3(uint D, uint Kmi, int Kri)
|
||||
{
|
||||
uint num = Kmi - D;
|
||||
num = (num << Kri) | (num >> 32 - Kri);
|
||||
return ((S1[(num >> 24) & 0xFF] + S2[(num >> 16) & 0xFF]) ^ S3[(num >> 8) & 0xFF]) - S4[num & 0xFF];
|
||||
}
|
||||
|
||||
internal void CAST_Encipher(uint L0, uint R0, uint[] result)
|
||||
{
|
||||
uint num = L0;
|
||||
uint num2 = R0;
|
||||
uint num3 = L0;
|
||||
uint num4 = R0;
|
||||
for (int i = 1; i <= _rounds; i++)
|
||||
{
|
||||
num = num3;
|
||||
num2 = num4;
|
||||
num3 = num2;
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 7:
|
||||
case 10:
|
||||
case 13:
|
||||
case 16:
|
||||
num4 = num ^ F1(num2, _Km[i], _Kr[i]);
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
case 8:
|
||||
case 11:
|
||||
case 14:
|
||||
num4 = num ^ F2(num2, _Km[i], _Kr[i]);
|
||||
break;
|
||||
case 3:
|
||||
case 6:
|
||||
case 9:
|
||||
case 12:
|
||||
case 15:
|
||||
num4 = num ^ F3(num2, _Km[i], _Kr[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result[0] = num4;
|
||||
result[1] = num3;
|
||||
}
|
||||
|
||||
internal void CAST_Decipher(uint L16, uint R16, uint[] result)
|
||||
{
|
||||
uint num = L16;
|
||||
uint num2 = R16;
|
||||
uint num3 = L16;
|
||||
uint num4 = R16;
|
||||
for (int num5 = _rounds; num5 > 0; num5--)
|
||||
{
|
||||
num = num3;
|
||||
num2 = num4;
|
||||
num3 = num2;
|
||||
switch (num5)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 7:
|
||||
case 10:
|
||||
case 13:
|
||||
case 16:
|
||||
num4 = num ^ F1(num2, _Km[num5], _Kr[num5]);
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
case 8:
|
||||
case 11:
|
||||
case 14:
|
||||
num4 = num ^ F2(num2, _Km[num5], _Kr[num5]);
|
||||
break;
|
||||
case 3:
|
||||
case 6:
|
||||
case 9:
|
||||
case 12:
|
||||
case 15:
|
||||
num4 = num ^ F3(num2, _Km[num5], _Kr[num5]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result[0] = num4;
|
||||
result[1] = num3;
|
||||
}
|
||||
|
||||
internal static void Bits32ToInts(uint inData, int[] b, int offset)
|
||||
{
|
||||
b[offset + 3] = (int)(inData & 0xFF);
|
||||
b[offset + 2] = (int)((inData >> 8) & 0xFF);
|
||||
b[offset + 1] = (int)((inData >> 16) & 0xFF);
|
||||
b[offset] = (int)((inData >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
internal static uint IntsTo32bits(int[] b, int i)
|
||||
{
|
||||
return (uint)(((b[i] & 0xFF) << 24) | ((b[i + 1] & 0xFF) << 16) | ((b[i + 2] & 0xFF) << 8) | (b[i + 3] & 0xFF));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public sealed class Cast6Engine : Cast5Engine
|
||||
{
|
||||
private const int ROUNDS = 12;
|
||||
|
||||
private const int BLOCK_SIZE = 16;
|
||||
|
||||
private int[] _Kr = new int[48];
|
||||
|
||||
private uint[] _Km = new uint[48];
|
||||
|
||||
private int[] _Tr = new int[192];
|
||||
|
||||
private uint[] _Tm = new uint[192];
|
||||
|
||||
private uint[] _workingKey = new uint[8];
|
||||
|
||||
public override string AlgorithmName => "CAST6";
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
public override int GetBlockSize()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
internal override void SetKey(byte[] key)
|
||||
{
|
||||
uint num = 1518500249u;
|
||||
uint num2 = 1859775393u;
|
||||
int num3 = 19;
|
||||
int num4 = 17;
|
||||
for (int i = 0; i < 24; i++)
|
||||
{
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
_Tm[i * 8 + j] = num;
|
||||
num += num2;
|
||||
_Tr[i * 8 + j] = num3;
|
||||
num3 = (num3 + num4) & 0x1F;
|
||||
}
|
||||
}
|
||||
byte[] array = new byte[64];
|
||||
key.CopyTo(array, 0);
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
_workingKey[k] = Pack.BE_To_UInt32(array, k * 4);
|
||||
}
|
||||
for (int l = 0; l < 12; l++)
|
||||
{
|
||||
int num5 = l * 2 * 8;
|
||||
uint[] workingKey;
|
||||
(workingKey = _workingKey)[6] = workingKey[6] ^ Cast5Engine.F1(_workingKey[7], _Tm[num5], _Tr[num5]);
|
||||
(workingKey = _workingKey)[5] = workingKey[5] ^ Cast5Engine.F2(_workingKey[6], _Tm[num5 + 1], _Tr[num5 + 1]);
|
||||
(workingKey = _workingKey)[4] = workingKey[4] ^ Cast5Engine.F3(_workingKey[5], _Tm[num5 + 2], _Tr[num5 + 2]);
|
||||
(workingKey = _workingKey)[3] = workingKey[3] ^ Cast5Engine.F1(_workingKey[4], _Tm[num5 + 3], _Tr[num5 + 3]);
|
||||
(workingKey = _workingKey)[2] = workingKey[2] ^ Cast5Engine.F2(_workingKey[3], _Tm[num5 + 4], _Tr[num5 + 4]);
|
||||
(workingKey = _workingKey)[1] = workingKey[1] ^ Cast5Engine.F3(_workingKey[2], _Tm[num5 + 5], _Tr[num5 + 5]);
|
||||
(workingKey = _workingKey)[0] = workingKey[0] ^ Cast5Engine.F1(_workingKey[1], _Tm[num5 + 6], _Tr[num5 + 6]);
|
||||
(workingKey = _workingKey)[7] = workingKey[7] ^ Cast5Engine.F2(_workingKey[0], _Tm[num5 + 7], _Tr[num5 + 7]);
|
||||
num5 = (l * 2 + 1) * 8;
|
||||
(workingKey = _workingKey)[6] = workingKey[6] ^ Cast5Engine.F1(_workingKey[7], _Tm[num5], _Tr[num5]);
|
||||
(workingKey = _workingKey)[5] = workingKey[5] ^ Cast5Engine.F2(_workingKey[6], _Tm[num5 + 1], _Tr[num5 + 1]);
|
||||
(workingKey = _workingKey)[4] = workingKey[4] ^ Cast5Engine.F3(_workingKey[5], _Tm[num5 + 2], _Tr[num5 + 2]);
|
||||
(workingKey = _workingKey)[3] = workingKey[3] ^ Cast5Engine.F1(_workingKey[4], _Tm[num5 + 3], _Tr[num5 + 3]);
|
||||
(workingKey = _workingKey)[2] = workingKey[2] ^ Cast5Engine.F2(_workingKey[3], _Tm[num5 + 4], _Tr[num5 + 4]);
|
||||
(workingKey = _workingKey)[1] = workingKey[1] ^ Cast5Engine.F3(_workingKey[2], _Tm[num5 + 5], _Tr[num5 + 5]);
|
||||
(workingKey = _workingKey)[0] = workingKey[0] ^ Cast5Engine.F1(_workingKey[1], _Tm[num5 + 6], _Tr[num5 + 6]);
|
||||
(workingKey = _workingKey)[7] = workingKey[7] ^ Cast5Engine.F2(_workingKey[0], _Tm[num5 + 7], _Tr[num5 + 7]);
|
||||
_Kr[l * 4] = (int)(_workingKey[0] & 0x1F);
|
||||
_Kr[l * 4 + 1] = (int)(_workingKey[2] & 0x1F);
|
||||
_Kr[l * 4 + 2] = (int)(_workingKey[4] & 0x1F);
|
||||
_Kr[l * 4 + 3] = (int)(_workingKey[6] & 0x1F);
|
||||
_Km[l * 4] = _workingKey[7];
|
||||
_Km[l * 4 + 1] = _workingKey[5];
|
||||
_Km[l * 4 + 2] = _workingKey[3];
|
||||
_Km[l * 4 + 3] = _workingKey[1];
|
||||
}
|
||||
}
|
||||
|
||||
internal override int EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
|
||||
{
|
||||
uint a = Pack.BE_To_UInt32(src, srcIndex);
|
||||
uint b = Pack.BE_To_UInt32(src, srcIndex + 4);
|
||||
uint c = Pack.BE_To_UInt32(src, srcIndex + 8);
|
||||
uint d = Pack.BE_To_UInt32(src, srcIndex + 12);
|
||||
uint[] array = new uint[4];
|
||||
CAST_Encipher(a, b, c, d, array);
|
||||
Pack.UInt32_To_BE(array[0], dst, dstIndex);
|
||||
Pack.UInt32_To_BE(array[1], dst, dstIndex + 4);
|
||||
Pack.UInt32_To_BE(array[2], dst, dstIndex + 8);
|
||||
Pack.UInt32_To_BE(array[3], dst, dstIndex + 12);
|
||||
return 16;
|
||||
}
|
||||
|
||||
internal override int DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
|
||||
{
|
||||
uint a = Pack.BE_To_UInt32(src, srcIndex);
|
||||
uint b = Pack.BE_To_UInt32(src, srcIndex + 4);
|
||||
uint c = Pack.BE_To_UInt32(src, srcIndex + 8);
|
||||
uint d = Pack.BE_To_UInt32(src, srcIndex + 12);
|
||||
uint[] array = new uint[4];
|
||||
CAST_Decipher(a, b, c, d, array);
|
||||
Pack.UInt32_To_BE(array[0], dst, dstIndex);
|
||||
Pack.UInt32_To_BE(array[1], dst, dstIndex + 4);
|
||||
Pack.UInt32_To_BE(array[2], dst, dstIndex + 8);
|
||||
Pack.UInt32_To_BE(array[3], dst, dstIndex + 12);
|
||||
return 16;
|
||||
}
|
||||
|
||||
private void CAST_Encipher(uint A, uint B, uint C, uint D, uint[] result)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
int num = i * 4;
|
||||
C ^= Cast5Engine.F1(D, _Km[num], _Kr[num]);
|
||||
B ^= Cast5Engine.F2(C, _Km[num + 1], _Kr[num + 1]);
|
||||
A ^= Cast5Engine.F3(B, _Km[num + 2], _Kr[num + 2]);
|
||||
D ^= Cast5Engine.F1(A, _Km[num + 3], _Kr[num + 3]);
|
||||
}
|
||||
for (int j = 6; j < 12; j++)
|
||||
{
|
||||
int num2 = j * 4;
|
||||
D ^= Cast5Engine.F1(A, _Km[num2 + 3], _Kr[num2 + 3]);
|
||||
A ^= Cast5Engine.F3(B, _Km[num2 + 2], _Kr[num2 + 2]);
|
||||
B ^= Cast5Engine.F2(C, _Km[num2 + 1], _Kr[num2 + 1]);
|
||||
C ^= Cast5Engine.F1(D, _Km[num2], _Kr[num2]);
|
||||
}
|
||||
result[0] = A;
|
||||
result[1] = B;
|
||||
result[2] = C;
|
||||
result[3] = D;
|
||||
}
|
||||
|
||||
private void CAST_Decipher(uint A, uint B, uint C, uint D, uint[] result)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
int num = (11 - i) * 4;
|
||||
C ^= Cast5Engine.F1(D, _Km[num], _Kr[num]);
|
||||
B ^= Cast5Engine.F2(C, _Km[num + 1], _Kr[num + 1]);
|
||||
A ^= Cast5Engine.F3(B, _Km[num + 2], _Kr[num + 2]);
|
||||
D ^= Cast5Engine.F1(A, _Km[num + 3], _Kr[num + 3]);
|
||||
}
|
||||
for (int j = 6; j < 12; j++)
|
||||
{
|
||||
int num2 = (11 - j) * 4;
|
||||
D ^= Cast5Engine.F1(A, _Km[num2 + 3], _Kr[num2 + 3]);
|
||||
A ^= Cast5Engine.F3(B, _Km[num2 + 2], _Kr[num2 + 2]);
|
||||
B ^= Cast5Engine.F2(C, _Km[num2 + 1], _Kr[num2 + 1]);
|
||||
C ^= Cast5Engine.F1(D, _Km[num2], _Kr[num2]);
|
||||
}
|
||||
result[0] = A;
|
||||
result[1] = B;
|
||||
result[2] = C;
|
||||
result[3] = D;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class ChaCha7539Engine : Salsa20Engine
|
||||
{
|
||||
public override string AlgorithmName => "ChaCha7539" + rounds;
|
||||
|
||||
protected override int NonceSize => 12;
|
||||
|
||||
protected override void AdvanceCounter()
|
||||
{
|
||||
uint[] array;
|
||||
if (((array = engineState)[12] = array[12] + 1) == 0)
|
||||
{
|
||||
throw new InvalidOperationException("attempt to increase counter past 2^32.");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ResetCounter()
|
||||
{
|
||||
engineState[12] = 0u;
|
||||
}
|
||||
|
||||
protected override void SetKey(byte[] keyBytes, byte[] ivBytes)
|
||||
{
|
||||
if (keyBytes != null)
|
||||
{
|
||||
if (keyBytes.Length != 32)
|
||||
{
|
||||
throw new ArgumentException(AlgorithmName + " requires 256 bit key");
|
||||
}
|
||||
PackTauOrSigma(keyBytes.Length, engineState, 0);
|
||||
Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 8);
|
||||
}
|
||||
Pack.LE_To_UInt32(ivBytes, 0, engineState, 13, 3);
|
||||
}
|
||||
|
||||
protected override void GenerateKeyStream(byte[] output)
|
||||
{
|
||||
ChaChaEngine.ChachaCore(rounds, engineState, x);
|
||||
Pack.UInt32_To_LE(x, output, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class ChaChaEngine : Salsa20Engine
|
||||
{
|
||||
public override string AlgorithmName => "ChaCha" + rounds;
|
||||
|
||||
public ChaChaEngine()
|
||||
{
|
||||
}
|
||||
|
||||
public ChaChaEngine(int rounds)
|
||||
: base(rounds)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void AdvanceCounter()
|
||||
{
|
||||
uint[] array;
|
||||
if (((array = engineState)[12] = array[12] + 1) == 0)
|
||||
{
|
||||
(array = engineState)[13] = array[13] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ResetCounter()
|
||||
{
|
||||
engineState[12] = (engineState[13] = 0u);
|
||||
}
|
||||
|
||||
protected override void SetKey(byte[] keyBytes, byte[] ivBytes)
|
||||
{
|
||||
if (keyBytes != null)
|
||||
{
|
||||
if (keyBytes.Length != 16 && keyBytes.Length != 32)
|
||||
{
|
||||
throw new ArgumentException(AlgorithmName + " requires 128 bit or 256 bit key");
|
||||
}
|
||||
PackTauOrSigma(keyBytes.Length, engineState, 0);
|
||||
Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 4);
|
||||
Pack.LE_To_UInt32(keyBytes, keyBytes.Length - 16, engineState, 8, 4);
|
||||
}
|
||||
Pack.LE_To_UInt32(ivBytes, 0, engineState, 14, 2);
|
||||
}
|
||||
|
||||
protected override void GenerateKeyStream(byte[] output)
|
||||
{
|
||||
ChachaCore(rounds, engineState, x);
|
||||
Pack.UInt32_To_LE(x, output, 0);
|
||||
}
|
||||
|
||||
internal static void ChachaCore(int rounds, uint[] input, uint[] x)
|
||||
{
|
||||
if (input.Length != 16)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
if (x.Length != 16)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
if (rounds % 2 != 0)
|
||||
{
|
||||
throw new ArgumentException("Number of rounds must be even");
|
||||
}
|
||||
uint num = input[0];
|
||||
uint num2 = input[1];
|
||||
uint num3 = input[2];
|
||||
uint num4 = input[3];
|
||||
uint num5 = input[4];
|
||||
uint num6 = input[5];
|
||||
uint num7 = input[6];
|
||||
uint num8 = input[7];
|
||||
uint num9 = input[8];
|
||||
uint num10 = input[9];
|
||||
uint num11 = input[10];
|
||||
uint num12 = input[11];
|
||||
uint num13 = input[12];
|
||||
uint num14 = input[13];
|
||||
uint num15 = input[14];
|
||||
uint num16 = input[15];
|
||||
for (int num17 = rounds; num17 > 0; num17 -= 2)
|
||||
{
|
||||
num += num5;
|
||||
num13 = Salsa20Engine.R(num13 ^ num, 16);
|
||||
num9 += num13;
|
||||
num5 = Salsa20Engine.R(num5 ^ num9, 12);
|
||||
num += num5;
|
||||
num13 = Salsa20Engine.R(num13 ^ num, 8);
|
||||
num9 += num13;
|
||||
num5 = Salsa20Engine.R(num5 ^ num9, 7);
|
||||
num2 += num6;
|
||||
num14 = Salsa20Engine.R(num14 ^ num2, 16);
|
||||
num10 += num14;
|
||||
num6 = Salsa20Engine.R(num6 ^ num10, 12);
|
||||
num2 += num6;
|
||||
num14 = Salsa20Engine.R(num14 ^ num2, 8);
|
||||
num10 += num14;
|
||||
num6 = Salsa20Engine.R(num6 ^ num10, 7);
|
||||
num3 += num7;
|
||||
num15 = Salsa20Engine.R(num15 ^ num3, 16);
|
||||
num11 += num15;
|
||||
num7 = Salsa20Engine.R(num7 ^ num11, 12);
|
||||
num3 += num7;
|
||||
num15 = Salsa20Engine.R(num15 ^ num3, 8);
|
||||
num11 += num15;
|
||||
num7 = Salsa20Engine.R(num7 ^ num11, 7);
|
||||
num4 += num8;
|
||||
num16 = Salsa20Engine.R(num16 ^ num4, 16);
|
||||
num12 += num16;
|
||||
num8 = Salsa20Engine.R(num8 ^ num12, 12);
|
||||
num4 += num8;
|
||||
num16 = Salsa20Engine.R(num16 ^ num4, 8);
|
||||
num12 += num16;
|
||||
num8 = Salsa20Engine.R(num8 ^ num12, 7);
|
||||
num += num6;
|
||||
num16 = Salsa20Engine.R(num16 ^ num, 16);
|
||||
num11 += num16;
|
||||
num6 = Salsa20Engine.R(num6 ^ num11, 12);
|
||||
num += num6;
|
||||
num16 = Salsa20Engine.R(num16 ^ num, 8);
|
||||
num11 += num16;
|
||||
num6 = Salsa20Engine.R(num6 ^ num11, 7);
|
||||
num2 += num7;
|
||||
num13 = Salsa20Engine.R(num13 ^ num2, 16);
|
||||
num12 += num13;
|
||||
num7 = Salsa20Engine.R(num7 ^ num12, 12);
|
||||
num2 += num7;
|
||||
num13 = Salsa20Engine.R(num13 ^ num2, 8);
|
||||
num12 += num13;
|
||||
num7 = Salsa20Engine.R(num7 ^ num12, 7);
|
||||
num3 += num8;
|
||||
num14 = Salsa20Engine.R(num14 ^ num3, 16);
|
||||
num9 += num14;
|
||||
num8 = Salsa20Engine.R(num8 ^ num9, 12);
|
||||
num3 += num8;
|
||||
num14 = Salsa20Engine.R(num14 ^ num3, 8);
|
||||
num9 += num14;
|
||||
num8 = Salsa20Engine.R(num8 ^ num9, 7);
|
||||
num4 += num5;
|
||||
num15 = Salsa20Engine.R(num15 ^ num4, 16);
|
||||
num10 += num15;
|
||||
num5 = Salsa20Engine.R(num5 ^ num10, 12);
|
||||
num4 += num5;
|
||||
num15 = Salsa20Engine.R(num15 ^ num4, 8);
|
||||
num10 += num15;
|
||||
num5 = Salsa20Engine.R(num5 ^ num10, 7);
|
||||
}
|
||||
x[0] = num + input[0];
|
||||
x[1] = num2 + input[1];
|
||||
x[2] = num3 + input[2];
|
||||
x[3] = num4 + input[3];
|
||||
x[4] = num5 + input[4];
|
||||
x[5] = num6 + input[5];
|
||||
x[6] = num7 + input[6];
|
||||
x[7] = num8 + input[7];
|
||||
x[8] = num9 + input[8];
|
||||
x[9] = num10 + input[9];
|
||||
x[10] = num11 + input[10];
|
||||
x[11] = num12 + input[11];
|
||||
x[12] = num13 + input[12];
|
||||
x[13] = num14 + input[13];
|
||||
x[14] = num15 + input[14];
|
||||
x[15] = num16 + input[15];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class DesEdeEngine : DesEngine
|
||||
{
|
||||
private int[] workingKey1;
|
||||
|
||||
private int[] workingKey2;
|
||||
|
||||
private int[] workingKey3;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
public override string AlgorithmName => "DESede";
|
||||
|
||||
public override void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter))
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to DESede init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
byte[] key = ((KeyParameter)parameters).GetKey();
|
||||
if (key.Length != 24 && key.Length != 16)
|
||||
{
|
||||
throw new ArgumentException("key size must be 16 or 24 bytes.");
|
||||
}
|
||||
this.forEncryption = forEncryption;
|
||||
byte[] array = new byte[8];
|
||||
Array.Copy(key, 0, array, 0, array.Length);
|
||||
workingKey1 = DesEngine.GenerateWorkingKey(forEncryption, array);
|
||||
byte[] array2 = new byte[8];
|
||||
Array.Copy(key, 8, array2, 0, array2.Length);
|
||||
workingKey2 = DesEngine.GenerateWorkingKey(!forEncryption, array2);
|
||||
if (key.Length == 24)
|
||||
{
|
||||
byte[] array3 = new byte[8];
|
||||
Array.Copy(key, 16, array3, 0, array3.Length);
|
||||
workingKey3 = DesEngine.GenerateWorkingKey(forEncryption, array3);
|
||||
}
|
||||
else
|
||||
{
|
||||
workingKey3 = workingKey1;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetBlockSize()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
public override int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (workingKey1 == null)
|
||||
{
|
||||
throw new InvalidOperationException("DESede engine not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 8, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 8, "output buffer too short");
|
||||
byte[] array = new byte[8];
|
||||
if (forEncryption)
|
||||
{
|
||||
DesEngine.DesFunc(workingKey1, input, inOff, array, 0);
|
||||
DesEngine.DesFunc(workingKey2, array, 0, array, 0);
|
||||
DesEngine.DesFunc(workingKey3, array, 0, output, outOff);
|
||||
}
|
||||
else
|
||||
{
|
||||
DesEngine.DesFunc(workingKey3, input, inOff, array, 0);
|
||||
DesEngine.DesFunc(workingKey2, array, 0, array, 0);
|
||||
DesEngine.DesFunc(workingKey1, array, 0, output, outOff);
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Digests;
|
||||
using Org.BouncyCastle.Crypto.Modes;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class DesEdeWrapEngine : IWrapper
|
||||
{
|
||||
private CbcBlockCipher engine;
|
||||
|
||||
private KeyParameter param;
|
||||
|
||||
private ParametersWithIV paramPlusIV;
|
||||
|
||||
private byte[] iv;
|
||||
|
||||
private bool forWrapping;
|
||||
|
||||
private static readonly byte[] IV2 = new byte[8] { 74, 221, 162, 44, 121, 232, 33, 5 };
|
||||
|
||||
private readonly IDigest sha1 = new Sha1Digest();
|
||||
|
||||
private readonly byte[] digest = new byte[20];
|
||||
|
||||
public virtual string AlgorithmName => "DESede";
|
||||
|
||||
public virtual void Init(bool forWrapping, ICipherParameters parameters)
|
||||
{
|
||||
this.forWrapping = forWrapping;
|
||||
engine = new CbcBlockCipher(new DesEdeEngine());
|
||||
SecureRandom secureRandom;
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
|
||||
parameters = parametersWithRandom.Parameters;
|
||||
secureRandom = parametersWithRandom.Random;
|
||||
}
|
||||
else
|
||||
{
|
||||
secureRandom = new SecureRandom();
|
||||
}
|
||||
if (parameters is KeyParameter)
|
||||
{
|
||||
param = (KeyParameter)parameters;
|
||||
if (this.forWrapping)
|
||||
{
|
||||
iv = new byte[8];
|
||||
secureRandom.NextBytes(iv);
|
||||
paramPlusIV = new ParametersWithIV(param, iv);
|
||||
}
|
||||
}
|
||||
else if (parameters is ParametersWithIV)
|
||||
{
|
||||
if (!forWrapping)
|
||||
{
|
||||
throw new ArgumentException("You should not supply an IV for unwrapping");
|
||||
}
|
||||
paramPlusIV = (ParametersWithIV)parameters;
|
||||
iv = paramPlusIV.GetIV();
|
||||
param = (KeyParameter)paramPlusIV.Parameters;
|
||||
if (iv.Length != 8)
|
||||
{
|
||||
throw new ArgumentException("IV is not 8 octets", "parameters");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] Wrap(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (!forWrapping)
|
||||
{
|
||||
throw new InvalidOperationException("Not initialized for wrapping");
|
||||
}
|
||||
byte[] array = new byte[length];
|
||||
Array.Copy(input, inOff, array, 0, length);
|
||||
byte[] array2 = CalculateCmsKeyChecksum(array);
|
||||
byte[] array3 = new byte[array.Length + array2.Length];
|
||||
Array.Copy(array, 0, array3, 0, array.Length);
|
||||
Array.Copy(array2, 0, array3, array.Length, array2.Length);
|
||||
int blockSize = engine.GetBlockSize();
|
||||
if (array3.Length % blockSize != 0)
|
||||
{
|
||||
throw new InvalidOperationException("Not multiple of block length");
|
||||
}
|
||||
engine.Init(forEncryption: true, paramPlusIV);
|
||||
byte[] array4 = new byte[array3.Length];
|
||||
for (int i = 0; i != array3.Length; i += blockSize)
|
||||
{
|
||||
engine.ProcessBlock(array3, i, array4, i);
|
||||
}
|
||||
byte[] array5 = new byte[iv.Length + array4.Length];
|
||||
Array.Copy(iv, 0, array5, 0, iv.Length);
|
||||
Array.Copy(array4, 0, array5, iv.Length, array4.Length);
|
||||
byte[] array6 = reverse(array5);
|
||||
ParametersWithIV parameters = new ParametersWithIV(param, IV2);
|
||||
engine.Init(forEncryption: true, parameters);
|
||||
for (int j = 0; j != array6.Length; j += blockSize)
|
||||
{
|
||||
engine.ProcessBlock(array6, j, array6, j);
|
||||
}
|
||||
return array6;
|
||||
}
|
||||
|
||||
public virtual byte[] Unwrap(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (forWrapping)
|
||||
{
|
||||
throw new InvalidOperationException("Not set for unwrapping");
|
||||
}
|
||||
if (input == null)
|
||||
{
|
||||
throw new InvalidCipherTextException("Null pointer as ciphertext");
|
||||
}
|
||||
int blockSize = engine.GetBlockSize();
|
||||
if (length % blockSize != 0)
|
||||
{
|
||||
throw new InvalidCipherTextException("Ciphertext not multiple of " + blockSize);
|
||||
}
|
||||
ParametersWithIV parameters = new ParametersWithIV(param, IV2);
|
||||
engine.Init(forEncryption: false, parameters);
|
||||
byte[] array = new byte[length];
|
||||
for (int i = 0; i != array.Length; i += blockSize)
|
||||
{
|
||||
engine.ProcessBlock(input, inOff + i, array, i);
|
||||
}
|
||||
byte[] array2 = reverse(array);
|
||||
iv = new byte[8];
|
||||
byte[] array3 = new byte[array2.Length - 8];
|
||||
Array.Copy(array2, 0, iv, 0, 8);
|
||||
Array.Copy(array2, 8, array3, 0, array2.Length - 8);
|
||||
paramPlusIV = new ParametersWithIV(param, iv);
|
||||
engine.Init(forEncryption: false, paramPlusIV);
|
||||
byte[] array4 = new byte[array3.Length];
|
||||
for (int j = 0; j != array4.Length; j += blockSize)
|
||||
{
|
||||
engine.ProcessBlock(array3, j, array4, j);
|
||||
}
|
||||
byte[] array5 = new byte[array4.Length - 8];
|
||||
byte[] array6 = new byte[8];
|
||||
Array.Copy(array4, 0, array5, 0, array4.Length - 8);
|
||||
Array.Copy(array4, array4.Length - 8, array6, 0, 8);
|
||||
if (!CheckCmsKeyChecksum(array5, array6))
|
||||
{
|
||||
throw new InvalidCipherTextException("Checksum inside ciphertext is corrupted");
|
||||
}
|
||||
return array5;
|
||||
}
|
||||
|
||||
private byte[] CalculateCmsKeyChecksum(byte[] key)
|
||||
{
|
||||
sha1.BlockUpdate(key, 0, key.Length);
|
||||
sha1.DoFinal(digest, 0);
|
||||
byte[] array = new byte[8];
|
||||
Array.Copy(digest, 0, array, 0, 8);
|
||||
return array;
|
||||
}
|
||||
|
||||
private bool CheckCmsKeyChecksum(byte[] key, byte[] checksum)
|
||||
{
|
||||
return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum);
|
||||
}
|
||||
|
||||
private static byte[] reverse(byte[] bs)
|
||||
{
|
||||
byte[] array = new byte[bs.Length];
|
||||
for (int i = 0; i < bs.Length; i++)
|
||||
{
|
||||
array[i] = bs[^(i + 1)];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class DesEngine : IBlockCipher
|
||||
{
|
||||
internal const int BLOCK_SIZE = 8;
|
||||
|
||||
private int[] workingKey;
|
||||
|
||||
private static readonly short[] bytebit = new short[8] { 128, 64, 32, 16, 8, 4, 2, 1 };
|
||||
|
||||
private static readonly int[] bigbyte = new int[24]
|
||||
{
|
||||
8388608, 4194304, 2097152, 1048576, 524288, 262144, 131072, 65536, 32768, 16384,
|
||||
8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16,
|
||||
8, 4, 2, 1
|
||||
};
|
||||
|
||||
private static readonly byte[] pc1 = new byte[56]
|
||||
{
|
||||
56, 48, 40, 32, 24, 16, 8, 0, 57, 49,
|
||||
41, 33, 25, 17, 9, 1, 58, 50, 42, 34,
|
||||
26, 18, 10, 2, 59, 51, 43, 35, 62, 54,
|
||||
46, 38, 30, 22, 14, 6, 61, 53, 45, 37,
|
||||
29, 21, 13, 5, 60, 52, 44, 36, 28, 20,
|
||||
12, 4, 27, 19, 11, 3
|
||||
};
|
||||
|
||||
private static readonly byte[] totrot = new byte[16]
|
||||
{
|
||||
1, 2, 4, 6, 8, 10, 12, 14, 15, 17,
|
||||
19, 21, 23, 25, 27, 28
|
||||
};
|
||||
|
||||
private static readonly byte[] pc2 = new byte[48]
|
||||
{
|
||||
13, 16, 10, 23, 0, 4, 2, 27, 14, 5,
|
||||
20, 9, 22, 18, 11, 3, 25, 7, 15, 6,
|
||||
26, 19, 12, 1, 40, 51, 30, 36, 46, 54,
|
||||
29, 39, 50, 44, 32, 47, 43, 48, 38, 55,
|
||||
33, 52, 45, 41, 49, 35, 28, 31
|
||||
};
|
||||
|
||||
private static readonly uint[] SP1 = new uint[64]
|
||||
{
|
||||
16843776u, 0u, 65536u, 16843780u, 16842756u, 66564u, 4u, 65536u, 1024u, 16843776u,
|
||||
16843780u, 1024u, 16778244u, 16842756u, 16777216u, 4u, 1028u, 16778240u, 16778240u, 66560u,
|
||||
66560u, 16842752u, 16842752u, 16778244u, 65540u, 16777220u, 16777220u, 65540u, 0u, 1028u,
|
||||
66564u, 16777216u, 65536u, 16843780u, 4u, 16842752u, 16843776u, 16777216u, 16777216u, 1024u,
|
||||
16842756u, 65536u, 66560u, 16777220u, 1024u, 4u, 16778244u, 66564u, 16843780u, 65540u,
|
||||
16842752u, 16778244u, 16777220u, 1028u, 66564u, 16843776u, 1028u, 16778240u, 16778240u, 0u,
|
||||
65540u, 66560u, 0u, 16842756u
|
||||
};
|
||||
|
||||
private static readonly uint[] SP2 = new uint[64]
|
||||
{
|
||||
2148565024u, 2147516416u, 32768u, 1081376u, 1048576u, 32u, 2148532256u, 2147516448u, 2147483680u, 2148565024u,
|
||||
2148564992u, 2147483648u, 2147516416u, 1048576u, 32u, 2148532256u, 1081344u, 1048608u, 2147516448u, 0u,
|
||||
2147483648u, 32768u, 1081376u, 2148532224u, 1048608u, 2147483680u, 0u, 1081344u, 32800u, 2148564992u,
|
||||
2148532224u, 32800u, 0u, 1081376u, 2148532256u, 1048576u, 2147516448u, 2148532224u, 2148564992u, 32768u,
|
||||
2148532224u, 2147516416u, 32u, 2148565024u, 1081376u, 32u, 32768u, 2147483648u, 32800u, 2148564992u,
|
||||
1048576u, 2147483680u, 1048608u, 2147516448u, 2147483680u, 1048608u, 1081344u, 0u, 2147516416u, 32800u,
|
||||
2147483648u, 2148532256u, 2148565024u, 1081344u
|
||||
};
|
||||
|
||||
private static readonly uint[] SP3 = new uint[64]
|
||||
{
|
||||
520u, 134349312u, 0u, 134348808u, 134218240u, 0u, 131592u, 134218240u, 131080u, 134217736u,
|
||||
134217736u, 131072u, 134349320u, 131080u, 134348800u, 520u, 134217728u, 8u, 134349312u, 512u,
|
||||
131584u, 134348800u, 134348808u, 131592u, 134218248u, 131584u, 131072u, 134218248u, 8u, 134349320u,
|
||||
512u, 134217728u, 134349312u, 134217728u, 131080u, 520u, 131072u, 134349312u, 134218240u, 0u,
|
||||
512u, 131080u, 134349320u, 134218240u, 134217736u, 512u, 0u, 134348808u, 134218248u, 131072u,
|
||||
134217728u, 134349320u, 8u, 131592u, 131584u, 134217736u, 134348800u, 134218248u, 520u, 134348800u,
|
||||
131592u, 8u, 134348808u, 131584u
|
||||
};
|
||||
|
||||
private static readonly uint[] SP4 = new uint[64]
|
||||
{
|
||||
8396801u, 8321u, 8321u, 128u, 8396928u, 8388737u, 8388609u, 8193u, 0u, 8396800u,
|
||||
8396800u, 8396929u, 129u, 0u, 8388736u, 8388609u, 1u, 8192u, 8388608u, 8396801u,
|
||||
128u, 8388608u, 8193u, 8320u, 8388737u, 1u, 8320u, 8388736u, 8192u, 8396928u,
|
||||
8396929u, 129u, 8388736u, 8388609u, 8396800u, 8396929u, 129u, 0u, 0u, 8396800u,
|
||||
8320u, 8388736u, 8388737u, 1u, 8396801u, 8321u, 8321u, 128u, 8396929u, 129u,
|
||||
1u, 8192u, 8388609u, 8193u, 8396928u, 8388737u, 8193u, 8320u, 8388608u, 8396801u,
|
||||
128u, 8388608u, 8192u, 8396928u
|
||||
};
|
||||
|
||||
private static readonly uint[] SP5 = new uint[64]
|
||||
{
|
||||
256u, 34078976u, 34078720u, 1107296512u, 524288u, 256u, 1073741824u, 34078720u, 1074266368u, 524288u,
|
||||
33554688u, 1074266368u, 1107296512u, 1107820544u, 524544u, 1073741824u, 33554432u, 1074266112u, 1074266112u, 0u,
|
||||
1073742080u, 1107820800u, 1107820800u, 33554688u, 1107820544u, 1073742080u, 0u, 1107296256u, 34078976u, 33554432u,
|
||||
1107296256u, 524544u, 524288u, 1107296512u, 256u, 33554432u, 1073741824u, 34078720u, 1107296512u, 1074266368u,
|
||||
33554688u, 1073741824u, 1107820544u, 34078976u, 1074266368u, 256u, 33554432u, 1107820544u, 1107820800u, 524544u,
|
||||
1107296256u, 1107820800u, 34078720u, 0u, 1074266112u, 1107296256u, 524544u, 33554688u, 1073742080u, 524288u,
|
||||
0u, 1074266112u, 34078976u, 1073742080u
|
||||
};
|
||||
|
||||
private static readonly uint[] SP6 = new uint[64]
|
||||
{
|
||||
536870928u, 541065216u, 16384u, 541081616u, 541065216u, 16u, 541081616u, 4194304u, 536887296u, 4210704u,
|
||||
4194304u, 536870928u, 4194320u, 536887296u, 536870912u, 16400u, 0u, 4194320u, 536887312u, 16384u,
|
||||
4210688u, 536887312u, 16u, 541065232u, 541065232u, 0u, 4210704u, 541081600u, 16400u, 4210688u,
|
||||
541081600u, 536870912u, 536887296u, 16u, 541065232u, 4210688u, 541081616u, 4194304u, 16400u, 536870928u,
|
||||
4194304u, 536887296u, 536870912u, 16400u, 536870928u, 541081616u, 4210688u, 541065216u, 4210704u, 541081600u,
|
||||
0u, 541065232u, 16u, 16384u, 541065216u, 4210704u, 16384u, 4194320u, 536887312u, 0u,
|
||||
541081600u, 536870912u, 4194320u, 536887312u
|
||||
};
|
||||
|
||||
private static readonly uint[] SP7 = new uint[64]
|
||||
{
|
||||
2097152u, 69206018u, 67110914u, 0u, 2048u, 67110914u, 2099202u, 69208064u, 69208066u, 2097152u,
|
||||
0u, 67108866u, 2u, 67108864u, 69206018u, 2050u, 67110912u, 2099202u, 2097154u, 67110912u,
|
||||
67108866u, 69206016u, 69208064u, 2097154u, 69206016u, 2048u, 2050u, 69208066u, 2099200u, 2u,
|
||||
67108864u, 2099200u, 67108864u, 2099200u, 2097152u, 67110914u, 67110914u, 69206018u, 69206018u, 2u,
|
||||
2097154u, 67108864u, 67110912u, 2097152u, 69208064u, 2050u, 2099202u, 69208064u, 2050u, 67108866u,
|
||||
69208066u, 69206016u, 2099200u, 0u, 2u, 69208066u, 0u, 2099202u, 69206016u, 2048u,
|
||||
67108866u, 67110912u, 2048u, 2097154u
|
||||
};
|
||||
|
||||
private static readonly uint[] SP8 = new uint[64]
|
||||
{
|
||||
268439616u, 4096u, 262144u, 268701760u, 268435456u, 268439616u, 64u, 268435456u, 262208u, 268697600u,
|
||||
268701760u, 266240u, 268701696u, 266304u, 4096u, 64u, 268697600u, 268435520u, 268439552u, 4160u,
|
||||
266240u, 262208u, 268697664u, 268701696u, 4160u, 0u, 0u, 268697664u, 268435520u, 268439552u,
|
||||
266304u, 262144u, 266304u, 262144u, 268701696u, 4096u, 64u, 268697664u, 4096u, 266304u,
|
||||
268439552u, 64u, 268435520u, 268697600u, 268697664u, 268435456u, 262144u, 268439616u, 0u, 268701760u,
|
||||
262208u, 268435520u, 268697600u, 268439552u, 268439616u, 0u, 268701760u, 266240u, 266240u, 4160u,
|
||||
4160u, 262208u, 268435456u, 268701696u
|
||||
};
|
||||
|
||||
public virtual string AlgorithmName => "DES";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
public virtual int[] GetWorkingKey()
|
||||
{
|
||||
return workingKey;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter))
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to DES init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
workingKey = GenerateWorkingKey(forEncryption, ((KeyParameter)parameters).GetKey());
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (workingKey == null)
|
||||
{
|
||||
throw new InvalidOperationException("DES engine not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 8, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 8, "output buffer too short");
|
||||
DesFunc(workingKey, input, inOff, output, outOff);
|
||||
return 8;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
protected static int[] GenerateWorkingKey(bool encrypting, byte[] key)
|
||||
{
|
||||
int[] array = new int[32];
|
||||
bool[] array2 = new bool[56];
|
||||
bool[] array3 = new bool[56];
|
||||
for (int i = 0; i < 56; i++)
|
||||
{
|
||||
int num = pc1[i];
|
||||
array2[i] = (key[num >>> 3] & bytebit[num & 7]) != 0;
|
||||
}
|
||||
for (int j = 0; j < 16; j++)
|
||||
{
|
||||
int num2 = ((!encrypting) ? (15 - j << 1) : (j << 1));
|
||||
int num3 = num2 + 1;
|
||||
array[num2] = (array[num3] = 0);
|
||||
for (int k = 0; k < 28; k++)
|
||||
{
|
||||
int num4 = k + totrot[j];
|
||||
if (num4 < 28)
|
||||
{
|
||||
array3[k] = array2[num4];
|
||||
}
|
||||
else
|
||||
{
|
||||
array3[k] = array2[num4 - 28];
|
||||
}
|
||||
}
|
||||
for (int l = 28; l < 56; l++)
|
||||
{
|
||||
int num4 = l + totrot[j];
|
||||
if (num4 < 56)
|
||||
{
|
||||
array3[l] = array2[num4];
|
||||
}
|
||||
else
|
||||
{
|
||||
array3[l] = array2[num4 - 28];
|
||||
}
|
||||
}
|
||||
for (int m = 0; m < 24; m++)
|
||||
{
|
||||
if (array3[pc2[m]])
|
||||
{
|
||||
int[] array5;
|
||||
int[] array4 = (array5 = array);
|
||||
nint num5 = num2;
|
||||
array4[num2] = array5[num5] | bigbyte[m];
|
||||
}
|
||||
if (array3[pc2[m + 24]])
|
||||
{
|
||||
int[] array5;
|
||||
int[] array6 = (array5 = array);
|
||||
nint num5 = num3;
|
||||
array6[num3] = array5[num5] | bigbyte[m];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int n = 0; n != 32; n += 2)
|
||||
{
|
||||
int num6 = array[n];
|
||||
int num7 = array[n + 1];
|
||||
array[n] = ((num6 & 0xFC0000) << 6) | ((num6 & 0xFC0) << 10) | ((num7 & 0xFC0000) >>> 10) | ((num7 & 0xFC0) >>> 6);
|
||||
array[n + 1] = ((num6 & 0x3F000) << 12) | ((num6 & 0x3F) << 16) | ((num7 & 0x3F000) >>> 4) | (num7 & 0x3F);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
internal static void DesFunc(int[] wKey, byte[] input, int inOff, byte[] outBytes, int outOff)
|
||||
{
|
||||
uint num = Pack.BE_To_UInt32(input, inOff);
|
||||
uint num2 = Pack.BE_To_UInt32(input, inOff + 4);
|
||||
uint num3 = ((num >> 4) ^ num2) & 0xF0F0F0F;
|
||||
num2 ^= num3;
|
||||
num ^= num3 << 4;
|
||||
num3 = ((num >> 16) ^ num2) & 0xFFFF;
|
||||
num2 ^= num3;
|
||||
num ^= num3 << 16;
|
||||
num3 = ((num2 >> 2) ^ num) & 0x33333333;
|
||||
num ^= num3;
|
||||
num2 ^= num3 << 2;
|
||||
num3 = ((num2 >> 8) ^ num) & 0xFF00FF;
|
||||
num ^= num3;
|
||||
num2 ^= num3 << 8;
|
||||
num2 = (num2 << 1) | (num2 >> 31);
|
||||
num3 = (num ^ num2) & 0xAAAAAAAAu;
|
||||
num ^= num3;
|
||||
num2 ^= num3;
|
||||
num = (num << 1) | (num >> 31);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
num3 = (num2 << 28) | (num2 >> 4);
|
||||
num3 ^= (uint)wKey[i * 4];
|
||||
uint num4 = SP7[num3 & 0x3F];
|
||||
num4 |= SP5[(num3 >> 8) & 0x3F];
|
||||
num4 |= SP3[(num3 >> 16) & 0x3F];
|
||||
num4 |= SP1[(num3 >> 24) & 0x3F];
|
||||
num3 = num2 ^ (uint)wKey[i * 4 + 1];
|
||||
num4 |= SP8[num3 & 0x3F];
|
||||
num4 |= SP6[(num3 >> 8) & 0x3F];
|
||||
num4 |= SP4[(num3 >> 16) & 0x3F];
|
||||
num4 |= SP2[(num3 >> 24) & 0x3F];
|
||||
num ^= num4;
|
||||
num3 = (num << 28) | (num >> 4);
|
||||
num3 ^= (uint)wKey[i * 4 + 2];
|
||||
num4 = SP7[num3 & 0x3F];
|
||||
num4 |= SP5[(num3 >> 8) & 0x3F];
|
||||
num4 |= SP3[(num3 >> 16) & 0x3F];
|
||||
num4 |= SP1[(num3 >> 24) & 0x3F];
|
||||
num3 = num ^ (uint)wKey[i * 4 + 3];
|
||||
num4 |= SP8[num3 & 0x3F];
|
||||
num4 |= SP6[(num3 >> 8) & 0x3F];
|
||||
num4 |= SP4[(num3 >> 16) & 0x3F];
|
||||
num4 |= SP2[(num3 >> 24) & 0x3F];
|
||||
num2 ^= num4;
|
||||
}
|
||||
num2 = (num2 << 31) | (num2 >> 1);
|
||||
num3 = (num ^ num2) & 0xAAAAAAAAu;
|
||||
num ^= num3;
|
||||
num2 ^= num3;
|
||||
num = (num << 31) | (num >> 1);
|
||||
num3 = ((num >> 8) ^ num2) & 0xFF00FF;
|
||||
num2 ^= num3;
|
||||
num ^= num3 << 8;
|
||||
num3 = ((num >> 2) ^ num2) & 0x33333333;
|
||||
num2 ^= num3;
|
||||
num ^= num3 << 2;
|
||||
num3 = ((num2 >> 16) ^ num) & 0xFFFF;
|
||||
num ^= num3;
|
||||
num2 ^= num3 << 16;
|
||||
num3 = ((num2 >> 4) ^ num) & 0xF0F0F0F;
|
||||
num ^= num3;
|
||||
num2 ^= num3 << 4;
|
||||
Pack.UInt32_To_BE(num2, outBytes, outOff);
|
||||
Pack.UInt32_To_BE(num, outBytes, outOff + 4);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class Dstu7624WrapEngine : IWrapper
|
||||
{
|
||||
private KeyParameter param;
|
||||
|
||||
private Dstu7624Engine engine;
|
||||
|
||||
private bool forWrapping;
|
||||
|
||||
private int blockSize;
|
||||
|
||||
public string AlgorithmName => "Dstu7624WrapEngine";
|
||||
|
||||
public Dstu7624WrapEngine(int blockSizeBits)
|
||||
{
|
||||
engine = new Dstu7624Engine(blockSizeBits);
|
||||
param = null;
|
||||
blockSize = blockSizeBits / 8;
|
||||
}
|
||||
|
||||
public void Init(bool forWrapping, ICipherParameters parameters)
|
||||
{
|
||||
this.forWrapping = forWrapping;
|
||||
if (parameters is KeyParameter)
|
||||
{
|
||||
param = (KeyParameter)parameters;
|
||||
engine.Init(forWrapping, param);
|
||||
return;
|
||||
}
|
||||
throw new ArgumentException("Bad parameters passed to Dstu7624WrapEngine");
|
||||
}
|
||||
|
||||
public byte[] Wrap(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (!forWrapping)
|
||||
{
|
||||
throw new InvalidOperationException("Not set for wrapping");
|
||||
}
|
||||
if (length % blockSize != 0)
|
||||
{
|
||||
throw new ArgumentException("Padding not supported");
|
||||
}
|
||||
int num = 2 * (1 + length / blockSize);
|
||||
int num2 = (num - 1) * 6;
|
||||
byte[] array = new byte[length + blockSize];
|
||||
Array.Copy(input, inOff, array, 0, length);
|
||||
byte[] array2 = new byte[blockSize / 2];
|
||||
Array.Copy(array, 0, array2, 0, blockSize / 2);
|
||||
IList list = Platform.CreateArrayList();
|
||||
int num3 = array.Length - blockSize / 2;
|
||||
int num4 = blockSize / 2;
|
||||
while (num3 != 0)
|
||||
{
|
||||
byte[] array3 = new byte[blockSize / 2];
|
||||
Array.Copy(array, num4, array3, 0, blockSize / 2);
|
||||
list.Add(array3);
|
||||
num3 -= blockSize / 2;
|
||||
num4 += blockSize / 2;
|
||||
}
|
||||
for (int i = 0; i < num2; i++)
|
||||
{
|
||||
Array.Copy(array2, 0, array, 0, blockSize / 2);
|
||||
Array.Copy((byte[])list[0], 0, array, blockSize / 2, blockSize / 2);
|
||||
engine.ProcessBlock(array, 0, array, 0);
|
||||
byte[] array4 = Pack.UInt32_To_LE((uint)(i + 1));
|
||||
for (int j = 0; j < array4.Length; j++)
|
||||
{
|
||||
byte[] array6;
|
||||
byte[] array5 = (array6 = array);
|
||||
int num5 = j + blockSize / 2;
|
||||
nint num6 = num5;
|
||||
array5[num5] = (byte)(array6[num6] ^ array4[j]);
|
||||
}
|
||||
Array.Copy(array, blockSize / 2, array2, 0, blockSize / 2);
|
||||
for (int k = 2; k < num; k++)
|
||||
{
|
||||
Array.Copy((byte[])list[k - 1], 0, (byte[])list[k - 2], 0, blockSize / 2);
|
||||
}
|
||||
Array.Copy(array, 0, (byte[])list[num - 2], 0, blockSize / 2);
|
||||
}
|
||||
Array.Copy(array2, 0, array, 0, blockSize / 2);
|
||||
num4 = blockSize / 2;
|
||||
for (int l = 0; l < num - 1; l++)
|
||||
{
|
||||
Array.Copy((byte[])list[l], 0, array, num4, blockSize / 2);
|
||||
num4 += blockSize / 2;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public byte[] Unwrap(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (forWrapping)
|
||||
{
|
||||
throw new InvalidOperationException("not set for unwrapping");
|
||||
}
|
||||
if (length % blockSize != 0)
|
||||
{
|
||||
throw new ArgumentException("Padding not supported");
|
||||
}
|
||||
int num = 2 * length / blockSize;
|
||||
int num2 = (num - 1) * 6;
|
||||
byte[] array = new byte[length];
|
||||
Array.Copy(input, inOff, array, 0, length);
|
||||
byte[] array2 = new byte[blockSize / 2];
|
||||
Array.Copy(array, 0, array2, 0, blockSize / 2);
|
||||
IList list = Platform.CreateArrayList();
|
||||
int num3 = array.Length - blockSize / 2;
|
||||
int num4 = blockSize / 2;
|
||||
while (num3 != 0)
|
||||
{
|
||||
byte[] array3 = new byte[blockSize / 2];
|
||||
Array.Copy(array, num4, array3, 0, blockSize / 2);
|
||||
list.Add(array3);
|
||||
num3 -= blockSize / 2;
|
||||
num4 += blockSize / 2;
|
||||
}
|
||||
for (int i = 0; i < num2; i++)
|
||||
{
|
||||
Array.Copy((byte[])list[num - 2], 0, array, 0, blockSize / 2);
|
||||
Array.Copy(array2, 0, array, blockSize / 2, blockSize / 2);
|
||||
byte[] array4 = Pack.UInt32_To_LE((uint)(num2 - i));
|
||||
for (int j = 0; j < array4.Length; j++)
|
||||
{
|
||||
byte[] array6;
|
||||
byte[] array5 = (array6 = array);
|
||||
int num5 = j + blockSize / 2;
|
||||
nint num6 = num5;
|
||||
array5[num5] = (byte)(array6[num6] ^ array4[j]);
|
||||
}
|
||||
engine.ProcessBlock(array, 0, array, 0);
|
||||
Array.Copy(array, 0, array2, 0, blockSize / 2);
|
||||
for (int k = 2; k < num; k++)
|
||||
{
|
||||
Array.Copy((byte[])list[num - k - 1], 0, (byte[])list[num - k], 0, blockSize / 2);
|
||||
}
|
||||
Array.Copy(array, blockSize / 2, (byte[])list[0], 0, blockSize / 2);
|
||||
}
|
||||
Array.Copy(array2, 0, array, 0, blockSize / 2);
|
||||
num4 = blockSize / 2;
|
||||
for (int l = 0; l < num - 1; l++)
|
||||
{
|
||||
Array.Copy((byte[])list[l], 0, array, num4, blockSize / 2);
|
||||
num4 += blockSize / 2;
|
||||
}
|
||||
byte b = 0;
|
||||
for (int m = array.Length - blockSize; m < array.Length; m++)
|
||||
{
|
||||
b |= array[m];
|
||||
}
|
||||
if (b != 0)
|
||||
{
|
||||
throw new InvalidCipherTextException("checksum failed");
|
||||
}
|
||||
return Arrays.CopyOfRange(array, 0, array.Length - blockSize);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class ElGamalEngine : IAsymmetricBlockCipher
|
||||
{
|
||||
private ElGamalKeyParameters key;
|
||||
|
||||
private SecureRandom random;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
private int bitSize;
|
||||
|
||||
public virtual string AlgorithmName => "ElGamal";
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
|
||||
key = (ElGamalKeyParameters)parametersWithRandom.Parameters;
|
||||
random = parametersWithRandom.Random;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = (ElGamalKeyParameters)parameters;
|
||||
random = new SecureRandom();
|
||||
}
|
||||
this.forEncryption = forEncryption;
|
||||
bitSize = key.Parameters.P.BitLength;
|
||||
if (forEncryption)
|
||||
{
|
||||
if (!(key is ElGamalPublicKeyParameters))
|
||||
{
|
||||
throw new ArgumentException("ElGamalPublicKeyParameters are required for encryption.");
|
||||
}
|
||||
}
|
||||
else if (!(key is ElGamalPrivateKeyParameters))
|
||||
{
|
||||
throw new ArgumentException("ElGamalPrivateKeyParameters are required for decryption.");
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int GetInputBlockSize()
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
return (bitSize - 1) / 8;
|
||||
}
|
||||
return 2 * ((bitSize + 7) / 8);
|
||||
}
|
||||
|
||||
public virtual int GetOutputBlockSize()
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
return 2 * ((bitSize + 7) / 8);
|
||||
}
|
||||
return (bitSize - 1) / 8;
|
||||
}
|
||||
|
||||
public virtual byte[] ProcessBlock(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
throw new InvalidOperationException("ElGamal engine not initialised");
|
||||
}
|
||||
int num = (forEncryption ? ((bitSize - 1 + 7) / 8) : GetInputBlockSize());
|
||||
if (length > num)
|
||||
{
|
||||
throw new DataLengthException("input too large for ElGamal cipher.\n");
|
||||
}
|
||||
BigInteger p = key.Parameters.P;
|
||||
byte[] array;
|
||||
if (key is ElGamalPrivateKeyParameters)
|
||||
{
|
||||
int num2 = length / 2;
|
||||
BigInteger bigInteger = new BigInteger(1, input, inOff, num2);
|
||||
BigInteger val = new BigInteger(1, input, inOff + num2, num2);
|
||||
ElGamalPrivateKeyParameters elGamalPrivateKeyParameters = (ElGamalPrivateKeyParameters)key;
|
||||
BigInteger bigInteger2 = bigInteger.ModPow(p.Subtract(BigInteger.One).Subtract(elGamalPrivateKeyParameters.X), p).Multiply(val).Mod(p);
|
||||
array = bigInteger2.ToByteArrayUnsigned();
|
||||
}
|
||||
else
|
||||
{
|
||||
BigInteger bigInteger3 = new BigInteger(1, input, inOff, length);
|
||||
if (bigInteger3.BitLength >= p.BitLength)
|
||||
{
|
||||
throw new DataLengthException("input too large for ElGamal cipher.\n");
|
||||
}
|
||||
ElGamalPublicKeyParameters elGamalPublicKeyParameters = (ElGamalPublicKeyParameters)key;
|
||||
BigInteger value = p.Subtract(BigInteger.Two);
|
||||
BigInteger bigInteger4;
|
||||
do
|
||||
{
|
||||
bigInteger4 = new BigInteger(p.BitLength, random);
|
||||
}
|
||||
while (bigInteger4.SignValue == 0 || bigInteger4.CompareTo(value) > 0);
|
||||
BigInteger g = key.Parameters.G;
|
||||
BigInteger bigInteger5 = g.ModPow(bigInteger4, p);
|
||||
BigInteger bigInteger6 = bigInteger3.Multiply(elGamalPublicKeyParameters.Y.ModPow(bigInteger4, p)).Mod(p);
|
||||
array = new byte[GetOutputBlockSize()];
|
||||
byte[] array2 = bigInteger5.ToByteArrayUnsigned();
|
||||
byte[] array3 = bigInteger6.ToByteArrayUnsigned();
|
||||
array2.CopyTo(array, array.Length / 2 - array2.Length);
|
||||
array3.CopyTo(array, array.Length - array3.Length);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class Gost28147Engine : IBlockCipher
|
||||
{
|
||||
private const int BlockSize = 8;
|
||||
|
||||
private int[] workingKey = null;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
private byte[] S = Sbox_Default;
|
||||
|
||||
private static readonly byte[] Sbox_Default;
|
||||
|
||||
private static readonly byte[] ESbox_Test;
|
||||
|
||||
private static readonly byte[] ESbox_A;
|
||||
|
||||
private static readonly byte[] ESbox_B;
|
||||
|
||||
private static readonly byte[] ESbox_C;
|
||||
|
||||
private static readonly byte[] ESbox_D;
|
||||
|
||||
private static readonly byte[] DSbox_Test;
|
||||
|
||||
private static readonly byte[] DSbox_A;
|
||||
|
||||
private static readonly IDictionary sBoxes;
|
||||
|
||||
public virtual string AlgorithmName => "Gost28147";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
static Gost28147Engine()
|
||||
{
|
||||
Sbox_Default = new byte[128]
|
||||
{
|
||||
4, 10, 9, 2, 13, 8, 0, 14, 6, 11,
|
||||
1, 12, 7, 15, 5, 3, 14, 11, 4, 12,
|
||||
6, 13, 15, 10, 2, 3, 8, 1, 0, 7,
|
||||
5, 9, 5, 8, 1, 13, 10, 3, 4, 2,
|
||||
14, 15, 12, 7, 6, 0, 9, 11, 7, 13,
|
||||
10, 1, 0, 8, 9, 15, 14, 4, 6, 12,
|
||||
11, 2, 5, 3, 6, 12, 7, 1, 5, 15,
|
||||
13, 8, 4, 10, 9, 14, 0, 3, 11, 2,
|
||||
4, 11, 10, 0, 7, 2, 1, 13, 3, 6,
|
||||
8, 5, 9, 12, 15, 14, 13, 11, 4, 1,
|
||||
3, 15, 5, 9, 0, 10, 14, 7, 6, 8,
|
||||
2, 12, 1, 15, 13, 0, 5, 7, 10, 4,
|
||||
9, 2, 3, 14, 6, 11, 8, 12
|
||||
};
|
||||
ESbox_Test = new byte[128]
|
||||
{
|
||||
4, 2, 15, 5, 9, 1, 0, 8, 14, 3,
|
||||
11, 12, 13, 7, 10, 6, 12, 9, 15, 14,
|
||||
8, 1, 3, 10, 2, 7, 4, 13, 6, 0,
|
||||
11, 5, 13, 8, 14, 12, 7, 3, 9, 10,
|
||||
1, 5, 2, 4, 6, 15, 0, 11, 14, 9,
|
||||
11, 2, 5, 15, 7, 1, 0, 13, 12, 6,
|
||||
10, 4, 3, 8, 3, 14, 5, 9, 6, 8,
|
||||
0, 13, 10, 11, 7, 12, 2, 1, 15, 4,
|
||||
8, 15, 6, 11, 1, 9, 12, 5, 13, 3,
|
||||
7, 10, 0, 14, 2, 4, 9, 11, 12, 0,
|
||||
3, 6, 7, 5, 4, 8, 14, 15, 1, 10,
|
||||
2, 13, 12, 6, 5, 2, 11, 0, 9, 13,
|
||||
3, 14, 7, 10, 15, 4, 1, 8
|
||||
};
|
||||
ESbox_A = new byte[128]
|
||||
{
|
||||
9, 6, 3, 2, 8, 11, 1, 7, 10, 4,
|
||||
14, 15, 12, 0, 13, 5, 3, 7, 14, 9,
|
||||
8, 10, 15, 0, 5, 2, 6, 12, 11, 4,
|
||||
13, 1, 14, 4, 6, 2, 11, 3, 13, 8,
|
||||
12, 15, 5, 10, 0, 7, 1, 9, 14, 7,
|
||||
10, 12, 13, 1, 3, 9, 0, 2, 11, 4,
|
||||
15, 8, 5, 6, 11, 5, 1, 9, 8, 13,
|
||||
15, 0, 14, 4, 2, 3, 12, 7, 10, 6,
|
||||
3, 10, 13, 12, 1, 2, 0, 11, 7, 5,
|
||||
9, 4, 8, 15, 14, 6, 1, 13, 2, 9,
|
||||
7, 10, 6, 0, 8, 12, 4, 5, 15, 3,
|
||||
11, 14, 11, 10, 15, 5, 0, 12, 14, 8,
|
||||
6, 2, 3, 9, 1, 7, 13, 4
|
||||
};
|
||||
ESbox_B = new byte[128]
|
||||
{
|
||||
8, 4, 11, 1, 3, 5, 0, 9, 2, 14,
|
||||
10, 12, 13, 6, 7, 15, 0, 1, 2, 10,
|
||||
4, 13, 5, 12, 9, 7, 3, 15, 11, 8,
|
||||
6, 14, 14, 12, 0, 10, 9, 2, 13, 11,
|
||||
7, 5, 8, 15, 3, 6, 1, 4, 7, 5,
|
||||
0, 13, 11, 6, 1, 2, 3, 10, 12, 15,
|
||||
4, 14, 9, 8, 2, 7, 12, 15, 9, 5,
|
||||
10, 11, 1, 4, 0, 13, 6, 8, 14, 3,
|
||||
8, 3, 2, 6, 4, 13, 14, 11, 12, 1,
|
||||
7, 15, 10, 0, 9, 5, 5, 2, 10, 11,
|
||||
9, 1, 12, 3, 7, 4, 13, 0, 6, 15,
|
||||
8, 14, 0, 4, 11, 14, 8, 3, 7, 1,
|
||||
10, 2, 9, 6, 15, 13, 5, 12
|
||||
};
|
||||
ESbox_C = new byte[128]
|
||||
{
|
||||
1, 11, 12, 2, 9, 13, 0, 15, 4, 5,
|
||||
8, 14, 10, 7, 6, 3, 0, 1, 7, 13,
|
||||
11, 4, 5, 2, 8, 14, 15, 12, 9, 10,
|
||||
6, 3, 8, 2, 5, 0, 4, 9, 15, 10,
|
||||
3, 7, 12, 13, 6, 14, 1, 11, 3, 6,
|
||||
0, 1, 5, 13, 10, 8, 11, 2, 9, 7,
|
||||
14, 15, 12, 4, 8, 13, 11, 0, 4, 5,
|
||||
1, 2, 9, 3, 12, 14, 6, 15, 10, 7,
|
||||
12, 9, 11, 1, 8, 14, 2, 4, 7, 3,
|
||||
6, 5, 10, 0, 15, 13, 10, 9, 6, 8,
|
||||
13, 14, 2, 0, 15, 3, 5, 11, 4, 1,
|
||||
12, 7, 7, 4, 0, 5, 10, 2, 15, 14,
|
||||
12, 6, 1, 11, 13, 9, 3, 8
|
||||
};
|
||||
ESbox_D = new byte[128]
|
||||
{
|
||||
15, 12, 2, 10, 6, 4, 5, 0, 7, 9,
|
||||
14, 13, 1, 11, 8, 3, 11, 6, 3, 4,
|
||||
12, 15, 14, 2, 7, 13, 8, 0, 5, 10,
|
||||
9, 1, 1, 12, 11, 0, 15, 14, 6, 5,
|
||||
10, 13, 4, 8, 9, 3, 7, 2, 1, 5,
|
||||
14, 12, 10, 7, 0, 13, 6, 2, 11, 4,
|
||||
9, 3, 15, 8, 0, 12, 8, 9, 13, 2,
|
||||
10, 11, 7, 3, 6, 5, 4, 14, 15, 1,
|
||||
8, 0, 15, 3, 2, 5, 14, 11, 1, 10,
|
||||
4, 7, 12, 9, 13, 6, 3, 0, 6, 15,
|
||||
1, 14, 9, 2, 13, 8, 12, 4, 11, 10,
|
||||
5, 7, 1, 10, 6, 8, 15, 11, 0, 4,
|
||||
12, 3, 5, 9, 7, 13, 2, 14
|
||||
};
|
||||
DSbox_Test = new byte[128]
|
||||
{
|
||||
4, 10, 9, 2, 13, 8, 0, 14, 6, 11,
|
||||
1, 12, 7, 15, 5, 3, 14, 11, 4, 12,
|
||||
6, 13, 15, 10, 2, 3, 8, 1, 0, 7,
|
||||
5, 9, 5, 8, 1, 13, 10, 3, 4, 2,
|
||||
14, 15, 12, 7, 6, 0, 9, 11, 7, 13,
|
||||
10, 1, 0, 8, 9, 15, 14, 4, 6, 12,
|
||||
11, 2, 5, 3, 6, 12, 7, 1, 5, 15,
|
||||
13, 8, 4, 10, 9, 14, 0, 3, 11, 2,
|
||||
4, 11, 10, 0, 7, 2, 1, 13, 3, 6,
|
||||
8, 5, 9, 12, 15, 14, 13, 11, 4, 1,
|
||||
3, 15, 5, 9, 0, 10, 14, 7, 6, 8,
|
||||
2, 12, 1, 15, 13, 0, 5, 7, 10, 4,
|
||||
9, 2, 3, 14, 6, 11, 8, 12
|
||||
};
|
||||
DSbox_A = new byte[128]
|
||||
{
|
||||
10, 4, 5, 6, 8, 1, 3, 7, 13, 12,
|
||||
14, 0, 9, 2, 11, 15, 5, 15, 4, 0,
|
||||
2, 13, 11, 9, 1, 7, 6, 3, 12, 14,
|
||||
10, 8, 7, 15, 12, 14, 9, 4, 1, 0,
|
||||
3, 11, 5, 2, 6, 10, 8, 13, 4, 10,
|
||||
7, 12, 0, 15, 2, 8, 14, 1, 6, 5,
|
||||
13, 11, 9, 3, 7, 6, 4, 11, 9, 12,
|
||||
2, 10, 1, 8, 0, 14, 15, 13, 3, 5,
|
||||
7, 6, 2, 4, 13, 9, 15, 0, 10, 1,
|
||||
5, 11, 8, 14, 12, 3, 13, 14, 4, 1,
|
||||
7, 0, 5, 10, 3, 12, 8, 15, 6, 2,
|
||||
9, 11, 1, 3, 10, 9, 5, 11, 4, 15,
|
||||
8, 6, 7, 14, 13, 0, 2, 12
|
||||
};
|
||||
sBoxes = Platform.CreateHashtable();
|
||||
AddSBox("Default", Sbox_Default);
|
||||
AddSBox("E-TEST", ESbox_Test);
|
||||
AddSBox("E-A", ESbox_A);
|
||||
AddSBox("E-B", ESbox_B);
|
||||
AddSBox("E-C", ESbox_C);
|
||||
AddSBox("E-D", ESbox_D);
|
||||
AddSBox("D-TEST", DSbox_Test);
|
||||
AddSBox("D-A", DSbox_A);
|
||||
}
|
||||
|
||||
private static void AddSBox(string sBoxName, byte[] sBox)
|
||||
{
|
||||
sBoxes.Add(Platform.ToUpperInvariant(sBoxName), sBox);
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (parameters is ParametersWithSBox)
|
||||
{
|
||||
ParametersWithSBox parametersWithSBox = (ParametersWithSBox)parameters;
|
||||
byte[] sBox = parametersWithSBox.GetSBox();
|
||||
if (sBox.Length != Sbox_Default.Length)
|
||||
{
|
||||
throw new ArgumentException("invalid S-box passed to GOST28147 init");
|
||||
}
|
||||
S = Arrays.Clone(sBox);
|
||||
if (parametersWithSBox.Parameters != null)
|
||||
{
|
||||
workingKey = generateWorkingKey(forEncryption, ((KeyParameter)parametersWithSBox.Parameters).GetKey());
|
||||
}
|
||||
}
|
||||
else if (parameters is KeyParameter)
|
||||
{
|
||||
workingKey = generateWorkingKey(forEncryption, ((KeyParameter)parameters).GetKey());
|
||||
}
|
||||
else if (parameters != null)
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to Gost28147 init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (workingKey == null)
|
||||
{
|
||||
throw new InvalidOperationException("Gost28147 engine not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 8, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 8, "output buffer too short");
|
||||
Gost28147Func(workingKey, input, inOff, output, outOff);
|
||||
return 8;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
private int[] generateWorkingKey(bool forEncryption, byte[] userKey)
|
||||
{
|
||||
this.forEncryption = forEncryption;
|
||||
if (userKey.Length != 32)
|
||||
{
|
||||
throw new ArgumentException("Key length invalid. Key needs to be 32 byte - 256 bit!!!");
|
||||
}
|
||||
int[] array = new int[8];
|
||||
for (int i = 0; i != 8; i++)
|
||||
{
|
||||
array[i] = bytesToint(userKey, i * 4);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private int Gost28147_mainStep(int n1, int key)
|
||||
{
|
||||
int num = key + n1;
|
||||
int num2 = S[num & 0xF];
|
||||
num2 += S[16 + ((num >> 4) & 0xF)] << 4;
|
||||
num2 += S[32 + ((num >> 8) & 0xF)] << 8;
|
||||
num2 += S[48 + ((num >> 12) & 0xF)] << 12;
|
||||
num2 += S[64 + ((num >> 16) & 0xF)] << 16;
|
||||
num2 += S[80 + ((num >> 20) & 0xF)] << 20;
|
||||
num2 += S[96 + ((num >> 24) & 0xF)] << 24;
|
||||
num2 += S[112 + ((num >> 28) & 0xF)] << 28;
|
||||
int num3 = num2 << 11;
|
||||
int num4 = num2 >>> 21;
|
||||
return num3 | num4;
|
||||
}
|
||||
|
||||
private void Gost28147Func(int[] workingKey, byte[] inBytes, int inOff, byte[] outBytes, int outOff)
|
||||
{
|
||||
int num = bytesToint(inBytes, inOff);
|
||||
int num2 = bytesToint(inBytes, inOff + 4);
|
||||
if (forEncryption)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
int num3 = num;
|
||||
int num4 = Gost28147_mainStep(num, workingKey[j]);
|
||||
num = num2 ^ num4;
|
||||
num2 = num3;
|
||||
}
|
||||
}
|
||||
for (int num5 = 7; num5 > 0; num5--)
|
||||
{
|
||||
int num3 = num;
|
||||
num = num2 ^ Gost28147_mainStep(num, workingKey[num5]);
|
||||
num2 = num3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
int num3 = num;
|
||||
num = num2 ^ Gost28147_mainStep(num, workingKey[k]);
|
||||
num2 = num3;
|
||||
}
|
||||
for (int l = 0; l < 3; l++)
|
||||
{
|
||||
int num6 = 7;
|
||||
while (num6 >= 0 && (l != 2 || num6 != 0))
|
||||
{
|
||||
int num3 = num;
|
||||
num = num2 ^ Gost28147_mainStep(num, workingKey[num6]);
|
||||
num2 = num3;
|
||||
num6--;
|
||||
}
|
||||
}
|
||||
}
|
||||
num2 ^= Gost28147_mainStep(num, workingKey[0]);
|
||||
intTobytes(num, outBytes, outOff);
|
||||
intTobytes(num2, outBytes, outOff + 4);
|
||||
}
|
||||
|
||||
private static int bytesToint(byte[] inBytes, int inOff)
|
||||
{
|
||||
return (int)((inBytes[inOff + 3] << 24) & 0xFF000000u) + ((inBytes[inOff + 2] << 16) & 0xFF0000) + ((inBytes[inOff + 1] << 8) & 0xFF00) + (inBytes[inOff] & 0xFF);
|
||||
}
|
||||
|
||||
private static void intTobytes(int num, byte[] outBytes, int outOff)
|
||||
{
|
||||
outBytes[outOff + 3] = (byte)(num >> 24);
|
||||
outBytes[outOff + 2] = (byte)(num >> 16);
|
||||
outBytes[outOff + 1] = (byte)(num >> 8);
|
||||
outBytes[outOff] = (byte)num;
|
||||
}
|
||||
|
||||
public static byte[] GetSBox(string sBoxName)
|
||||
{
|
||||
byte[] array = (byte[])sBoxes[Platform.ToUpperInvariant(sBoxName)];
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentException("Unknown S-Box - possible types: \"Default\", \"E-Test\", \"E-A\", \"E-B\", \"E-C\", \"E-D\", \"D-Test\", \"D-A\".");
|
||||
}
|
||||
return Arrays.Clone(array);
|
||||
}
|
||||
|
||||
public static string GetSBoxName(byte[] sBox)
|
||||
{
|
||||
foreach (string key in sBoxes.Keys)
|
||||
{
|
||||
byte[] a = (byte[])sBoxes[key];
|
||||
if (Arrays.AreEqual(a, sBox))
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
throw new ArgumentException("SBOX provided did not map to a known one");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class HC128Engine : IStreamCipher
|
||||
{
|
||||
private uint[] p = new uint[512];
|
||||
|
||||
private uint[] q = new uint[512];
|
||||
|
||||
private uint cnt = 0u;
|
||||
|
||||
private byte[] key;
|
||||
|
||||
private byte[] iv;
|
||||
|
||||
private bool initialised;
|
||||
|
||||
private byte[] buf = new byte[4];
|
||||
|
||||
private int idx = 0;
|
||||
|
||||
public virtual string AlgorithmName => "HC-128";
|
||||
|
||||
private static uint F1(uint x)
|
||||
{
|
||||
return RotateRight(x, 7) ^ RotateRight(x, 18) ^ (x >> 3);
|
||||
}
|
||||
|
||||
private static uint F2(uint x)
|
||||
{
|
||||
return RotateRight(x, 17) ^ RotateRight(x, 19) ^ (x >> 10);
|
||||
}
|
||||
|
||||
private uint G1(uint x, uint y, uint z)
|
||||
{
|
||||
return (RotateRight(x, 10) ^ RotateRight(z, 23)) + RotateRight(y, 8);
|
||||
}
|
||||
|
||||
private uint G2(uint x, uint y, uint z)
|
||||
{
|
||||
return (RotateLeft(x, 10) ^ RotateLeft(z, 23)) + RotateLeft(y, 8);
|
||||
}
|
||||
|
||||
private static uint RotateLeft(uint x, int bits)
|
||||
{
|
||||
return (x << bits) | (x >> -bits);
|
||||
}
|
||||
|
||||
private static uint RotateRight(uint x, int bits)
|
||||
{
|
||||
return (x >> bits) | (x << -bits);
|
||||
}
|
||||
|
||||
private uint H1(uint x)
|
||||
{
|
||||
return q[x & 0xFF] + q[((x >> 16) & 0xFF) + 256];
|
||||
}
|
||||
|
||||
private uint H2(uint x)
|
||||
{
|
||||
return p[x & 0xFF] + p[((x >> 16) & 0xFF) + 256];
|
||||
}
|
||||
|
||||
private static uint Mod1024(uint x)
|
||||
{
|
||||
return x & 0x3FF;
|
||||
}
|
||||
|
||||
private static uint Mod512(uint x)
|
||||
{
|
||||
return x & 0x1FF;
|
||||
}
|
||||
|
||||
private static uint Dim(uint x, uint y)
|
||||
{
|
||||
return Mod512(x - y);
|
||||
}
|
||||
|
||||
private uint Step()
|
||||
{
|
||||
uint num = Mod512(cnt);
|
||||
uint result;
|
||||
if (cnt < 512)
|
||||
{
|
||||
uint[] array;
|
||||
nint num2;
|
||||
(array = p)[num2 = (nint)num] = array[num2] + G1(p[Dim(num, 3u)], p[Dim(num, 10u)], p[Dim(num, 511u)]);
|
||||
result = H1(p[Dim(num, 12u)]) ^ p[num];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint[] array;
|
||||
nint num2;
|
||||
(array = q)[num2 = (nint)num] = array[num2] + G2(q[Dim(num, 3u)], q[Dim(num, 10u)], q[Dim(num, 511u)]);
|
||||
result = H2(q[Dim(num, 12u)]) ^ q[num];
|
||||
}
|
||||
cnt = Mod1024(cnt + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (key.Length != 16)
|
||||
{
|
||||
throw new ArgumentException("The key must be 128 bits long");
|
||||
}
|
||||
idx = 0;
|
||||
cnt = 0u;
|
||||
uint[] array = new uint[1280];
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
uint[] array3;
|
||||
uint[] array2 = (array3 = array);
|
||||
int num = i >> 2;
|
||||
nint num2 = num;
|
||||
array2[num] = array3[num2] | (uint)(key[i] << 8 * (i & 3));
|
||||
}
|
||||
Array.Copy(array, 0, array, 4, 4);
|
||||
for (int j = 0; j < iv.Length && j < 16; j++)
|
||||
{
|
||||
uint[] array3;
|
||||
uint[] array4 = (array3 = array);
|
||||
int num3 = (j >> 2) + 8;
|
||||
nint num2 = num3;
|
||||
array4[num3] = array3[num2] | (uint)(iv[j] << 8 * (j & 3));
|
||||
}
|
||||
Array.Copy(array, 8, array, 12, 4);
|
||||
for (uint num4 = 16u; num4 < 1280; num4++)
|
||||
{
|
||||
array[num4] = F2(array[num4 - 2]) + array[num4 - 7] + F1(array[num4 - 15]) + array[num4 - 16] + num4;
|
||||
}
|
||||
Array.Copy(array, 256, p, 0, 512);
|
||||
Array.Copy(array, 768, q, 0, 512);
|
||||
for (int k = 0; k < 512; k++)
|
||||
{
|
||||
p[k] = Step();
|
||||
}
|
||||
for (int l = 0; l < 512; l++)
|
||||
{
|
||||
q[l] = Step();
|
||||
}
|
||||
cnt = 0u;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
ICipherParameters cipherParameters = parameters;
|
||||
if (parameters is ParametersWithIV)
|
||||
{
|
||||
iv = ((ParametersWithIV)parameters).GetIV();
|
||||
cipherParameters = ((ParametersWithIV)parameters).Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
iv = new byte[0];
|
||||
}
|
||||
if (cipherParameters is KeyParameter)
|
||||
{
|
||||
key = ((KeyParameter)cipherParameters).GetKey();
|
||||
Init();
|
||||
initialised = true;
|
||||
return;
|
||||
}
|
||||
throw new ArgumentException("Invalid parameter passed to HC128 init - " + Platform.GetTypeName(parameters), "parameters");
|
||||
}
|
||||
|
||||
private byte GetByte()
|
||||
{
|
||||
if (idx == 0)
|
||||
{
|
||||
Pack.UInt32_To_LE(Step(), buf);
|
||||
}
|
||||
byte result = buf[idx];
|
||||
idx = (idx + 1) & 3;
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual void ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
|
||||
{
|
||||
if (!initialised)
|
||||
{
|
||||
throw new InvalidOperationException(AlgorithmName + " not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, len, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, len, "output buffer too short");
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
output[outOff + i] = (byte)(input[inOff + i] ^ GetByte());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public virtual byte ReturnByte(byte input)
|
||||
{
|
||||
return (byte)(input ^ GetByte());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class HC256Engine : IStreamCipher
|
||||
{
|
||||
private uint[] p = new uint[1024];
|
||||
|
||||
private uint[] q = new uint[1024];
|
||||
|
||||
private uint cnt = 0u;
|
||||
|
||||
private byte[] key;
|
||||
|
||||
private byte[] iv;
|
||||
|
||||
private bool initialised;
|
||||
|
||||
private byte[] buf = new byte[4];
|
||||
|
||||
private int idx = 0;
|
||||
|
||||
public virtual string AlgorithmName => "HC-256";
|
||||
|
||||
private uint Step()
|
||||
{
|
||||
uint num = cnt & 0x3FF;
|
||||
uint result;
|
||||
if (cnt < 1024)
|
||||
{
|
||||
uint num2 = p[(num - 3) & 0x3FF];
|
||||
uint num3 = p[(num - 1023) & 0x3FF];
|
||||
uint[] array;
|
||||
nint num4;
|
||||
(array = p)[num4 = (nint)num] = array[num4] + (p[(num - 10) & 0x3FF] + (RotateRight(num2, 10) ^ RotateRight(num3, 23)) + q[(num2 ^ num3) & 0x3FF]);
|
||||
num2 = p[(num - 12) & 0x3FF];
|
||||
result = (q[num2 & 0xFF] + q[((num2 >> 8) & 0xFF) + 256] + q[((num2 >> 16) & 0xFF) + 512] + q[((num2 >> 24) & 0xFF) + 768]) ^ p[num];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint num5 = q[(num - 3) & 0x3FF];
|
||||
uint num6 = q[(num - 1023) & 0x3FF];
|
||||
uint[] array;
|
||||
nint num4;
|
||||
(array = q)[num4 = (nint)num] = array[num4] + (q[(num - 10) & 0x3FF] + (RotateRight(num5, 10) ^ RotateRight(num6, 23)) + p[(num5 ^ num6) & 0x3FF]);
|
||||
num5 = q[(num - 12) & 0x3FF];
|
||||
result = (p[num5 & 0xFF] + p[((num5 >> 8) & 0xFF) + 256] + p[((num5 >> 16) & 0xFF) + 512] + p[((num5 >> 24) & 0xFF) + 768]) ^ q[num];
|
||||
}
|
||||
cnt = (cnt + 1) & 0x7FF;
|
||||
return result;
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (key.Length != 32 && key.Length != 16)
|
||||
{
|
||||
throw new ArgumentException("The key must be 128/256 bits long");
|
||||
}
|
||||
if (iv.Length < 16)
|
||||
{
|
||||
throw new ArgumentException("The IV must be at least 128 bits long");
|
||||
}
|
||||
if (key.Length != 32)
|
||||
{
|
||||
byte[] destinationArray = new byte[32];
|
||||
Array.Copy(key, 0, destinationArray, 0, key.Length);
|
||||
Array.Copy(key, 0, destinationArray, 16, key.Length);
|
||||
key = destinationArray;
|
||||
}
|
||||
if (iv.Length < 32)
|
||||
{
|
||||
byte[] array = new byte[32];
|
||||
Array.Copy(iv, 0, array, 0, iv.Length);
|
||||
Array.Copy(iv, 0, array, iv.Length, array.Length - iv.Length);
|
||||
iv = array;
|
||||
}
|
||||
idx = 0;
|
||||
cnt = 0u;
|
||||
uint[] array2 = new uint[2560];
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
uint[] array4;
|
||||
uint[] array3 = (array4 = array2);
|
||||
int num = i >> 2;
|
||||
nint num2 = num;
|
||||
array3[num] = array4[num2] | (uint)(key[i] << 8 * (i & 3));
|
||||
}
|
||||
for (int j = 0; j < 32; j++)
|
||||
{
|
||||
uint[] array4;
|
||||
uint[] array5 = (array4 = array2);
|
||||
int num3 = (j >> 2) + 8;
|
||||
nint num2 = num3;
|
||||
array5[num3] = array4[num2] | (uint)(iv[j] << 8 * (j & 3));
|
||||
}
|
||||
for (uint num4 = 16u; num4 < 2560; num4++)
|
||||
{
|
||||
uint num5 = array2[num4 - 2];
|
||||
uint num6 = array2[num4 - 15];
|
||||
array2[num4] = (RotateRight(num5, 17) ^ RotateRight(num5, 19) ^ (num5 >> 10)) + array2[num4 - 7] + (RotateRight(num6, 7) ^ RotateRight(num6, 18) ^ (num6 >> 3)) + array2[num4 - 16] + num4;
|
||||
}
|
||||
Array.Copy(array2, 512, p, 0, 1024);
|
||||
Array.Copy(array2, 1536, q, 0, 1024);
|
||||
for (int k = 0; k < 4096; k++)
|
||||
{
|
||||
Step();
|
||||
}
|
||||
cnt = 0u;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
ICipherParameters cipherParameters = parameters;
|
||||
if (parameters is ParametersWithIV)
|
||||
{
|
||||
iv = ((ParametersWithIV)parameters).GetIV();
|
||||
cipherParameters = ((ParametersWithIV)parameters).Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
iv = new byte[0];
|
||||
}
|
||||
if (cipherParameters is KeyParameter)
|
||||
{
|
||||
key = ((KeyParameter)cipherParameters).GetKey();
|
||||
Init();
|
||||
initialised = true;
|
||||
return;
|
||||
}
|
||||
throw new ArgumentException("Invalid parameter passed to HC256 init - " + Platform.GetTypeName(parameters), "parameters");
|
||||
}
|
||||
|
||||
private byte GetByte()
|
||||
{
|
||||
if (idx == 0)
|
||||
{
|
||||
Pack.UInt32_To_LE(Step(), buf);
|
||||
}
|
||||
byte result = buf[idx];
|
||||
idx = (idx + 1) & 3;
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual void ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
|
||||
{
|
||||
if (!initialised)
|
||||
{
|
||||
throw new InvalidOperationException(AlgorithmName + " not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, len, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, len, "output buffer too short");
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
output[outOff + i] = (byte)(input[inOff + i] ^ GetByte());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public virtual byte ReturnByte(byte input)
|
||||
{
|
||||
return (byte)(input ^ GetByte());
|
||||
}
|
||||
|
||||
private static uint RotateRight(uint x, int bits)
|
||||
{
|
||||
return (x >> bits) | (x << -bits);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class IdeaEngine : IBlockCipher
|
||||
{
|
||||
private const int BLOCK_SIZE = 8;
|
||||
|
||||
private int[] workingKey;
|
||||
|
||||
private static readonly int MASK = 65535;
|
||||
|
||||
private static readonly int BASE = 65537;
|
||||
|
||||
public virtual string AlgorithmName => "IDEA";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter))
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to IDEA init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
workingKey = GenerateWorkingKey(forEncryption, ((KeyParameter)parameters).GetKey());
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
||||
{
|
||||
if (workingKey == null)
|
||||
{
|
||||
throw new InvalidOperationException("IDEA engine not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, 8, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, 8, "output buffer too short");
|
||||
IdeaFunc(workingKey, input, inOff, output, outOff);
|
||||
return 8;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
private int BytesToWord(byte[] input, int inOff)
|
||||
{
|
||||
return ((input[inOff] << 8) & 0xFF00) + (input[inOff + 1] & 0xFF);
|
||||
}
|
||||
|
||||
private void WordToBytes(int word, byte[] outBytes, int outOff)
|
||||
{
|
||||
outBytes[outOff] = (byte)((uint)word >> 8);
|
||||
outBytes[outOff + 1] = (byte)word;
|
||||
}
|
||||
|
||||
private int Mul(int x, int y)
|
||||
{
|
||||
if (x == 0)
|
||||
{
|
||||
x = BASE - y;
|
||||
}
|
||||
else if (y == 0)
|
||||
{
|
||||
x = BASE - x;
|
||||
}
|
||||
else
|
||||
{
|
||||
int num = x * y;
|
||||
y = num & MASK;
|
||||
x = num >>> 16;
|
||||
x = y - x + ((y < x) ? 1 : 0);
|
||||
}
|
||||
return x & MASK;
|
||||
}
|
||||
|
||||
private void IdeaFunc(int[] workingKey, byte[] input, int inOff, byte[] outBytes, int outOff)
|
||||
{
|
||||
int num = 0;
|
||||
int x = BytesToWord(input, inOff);
|
||||
int num2 = BytesToWord(input, inOff + 2);
|
||||
int num3 = BytesToWord(input, inOff + 4);
|
||||
int x2 = BytesToWord(input, inOff + 6);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
x = Mul(x, workingKey[num++]);
|
||||
num2 += workingKey[num++];
|
||||
num2 &= MASK;
|
||||
num3 += workingKey[num++];
|
||||
num3 &= MASK;
|
||||
x2 = Mul(x2, workingKey[num++]);
|
||||
int num4 = num2;
|
||||
int num5 = num3;
|
||||
num3 ^= x;
|
||||
num2 ^= x2;
|
||||
num3 = Mul(num3, workingKey[num++]);
|
||||
num2 += num3;
|
||||
num2 &= MASK;
|
||||
num2 = Mul(num2, workingKey[num++]);
|
||||
num3 += num2;
|
||||
num3 &= MASK;
|
||||
x ^= num2;
|
||||
x2 ^= num3;
|
||||
num2 ^= num5;
|
||||
num3 ^= num4;
|
||||
}
|
||||
WordToBytes(Mul(x, workingKey[num++]), outBytes, outOff);
|
||||
WordToBytes(num3 + workingKey[num++], outBytes, outOff + 2);
|
||||
WordToBytes(num2 + workingKey[num++], outBytes, outOff + 4);
|
||||
WordToBytes(Mul(x2, workingKey[num]), outBytes, outOff + 6);
|
||||
}
|
||||
|
||||
private int[] ExpandKey(byte[] uKey)
|
||||
{
|
||||
int[] array = new int[52];
|
||||
if (uKey.Length < 16)
|
||||
{
|
||||
byte[] array2 = new byte[16];
|
||||
Array.Copy(uKey, 0, array2, array2.Length - uKey.Length, uKey.Length);
|
||||
uKey = array2;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
array[i] = BytesToWord(uKey, i * 2);
|
||||
}
|
||||
for (int j = 8; j < 52; j++)
|
||||
{
|
||||
if ((j & 7) < 6)
|
||||
{
|
||||
array[j] = (((array[j - 7] & 0x7F) << 9) | (array[j - 6] >> 7)) & MASK;
|
||||
}
|
||||
else if ((j & 7) == 6)
|
||||
{
|
||||
array[j] = (((array[j - 7] & 0x7F) << 9) | (array[j - 14] >> 7)) & MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
array[j] = (((array[j - 15] & 0x7F) << 9) | (array[j - 14] >> 7)) & MASK;
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private int MulInv(int x)
|
||||
{
|
||||
if (x < 2)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
int num = 1;
|
||||
int num2 = BASE / x;
|
||||
int num3 = BASE % x;
|
||||
while (num3 != 1)
|
||||
{
|
||||
int num4 = x / num3;
|
||||
x %= num3;
|
||||
num = (num + num2 * num4) & MASK;
|
||||
if (x == 1)
|
||||
{
|
||||
return num;
|
||||
}
|
||||
num4 = num3 / x;
|
||||
num3 %= x;
|
||||
num2 = (num2 + num * num4) & MASK;
|
||||
}
|
||||
return (1 - num2) & MASK;
|
||||
}
|
||||
|
||||
private int AddInv(int x)
|
||||
{
|
||||
return -x & MASK;
|
||||
}
|
||||
|
||||
private int[] InvertKey(int[] inKey)
|
||||
{
|
||||
int num = 52;
|
||||
int[] array = new int[52];
|
||||
int num2 = 0;
|
||||
int num3 = MulInv(inKey[num2++]);
|
||||
int num4 = AddInv(inKey[num2++]);
|
||||
int num5 = AddInv(inKey[num2++]);
|
||||
int num6 = MulInv(inKey[num2++]);
|
||||
array[--num] = num6;
|
||||
array[--num] = num5;
|
||||
array[--num] = num4;
|
||||
array[--num] = num3;
|
||||
for (int i = 1; i < 8; i++)
|
||||
{
|
||||
num3 = inKey[num2++];
|
||||
num4 = inKey[num2++];
|
||||
array[--num] = num4;
|
||||
array[--num] = num3;
|
||||
num3 = MulInv(inKey[num2++]);
|
||||
num4 = AddInv(inKey[num2++]);
|
||||
num5 = AddInv(inKey[num2++]);
|
||||
num6 = MulInv(inKey[num2++]);
|
||||
array[--num] = num6;
|
||||
array[--num] = num4;
|
||||
array[--num] = num5;
|
||||
array[--num] = num3;
|
||||
}
|
||||
num3 = inKey[num2++];
|
||||
num4 = inKey[num2++];
|
||||
array[--num] = num4;
|
||||
array[--num] = num3;
|
||||
num3 = MulInv(inKey[num2++]);
|
||||
num4 = AddInv(inKey[num2++]);
|
||||
num5 = AddInv(inKey[num2++]);
|
||||
num6 = MulInv(inKey[num2]);
|
||||
array[--num] = num6;
|
||||
array[--num] = num5;
|
||||
array[--num] = num4;
|
||||
array[--num] = num3;
|
||||
return array;
|
||||
}
|
||||
|
||||
private int[] GenerateWorkingKey(bool forEncryption, byte[] userKey)
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
return ExpandKey(userKey);
|
||||
}
|
||||
return InvertKey(ExpandKey(userKey));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class IesEngine
|
||||
{
|
||||
private readonly IBasicAgreement agree;
|
||||
|
||||
private readonly IDerivationFunction kdf;
|
||||
|
||||
private readonly IMac mac;
|
||||
|
||||
private readonly BufferedBlockCipher cipher;
|
||||
|
||||
private readonly byte[] macBuf;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
private ICipherParameters privParam;
|
||||
|
||||
private ICipherParameters pubParam;
|
||||
|
||||
private IesParameters param;
|
||||
|
||||
public IesEngine(IBasicAgreement agree, IDerivationFunction kdf, IMac mac)
|
||||
{
|
||||
this.agree = agree;
|
||||
this.kdf = kdf;
|
||||
this.mac = mac;
|
||||
macBuf = new byte[mac.GetMacSize()];
|
||||
}
|
||||
|
||||
public IesEngine(IBasicAgreement agree, IDerivationFunction kdf, IMac mac, BufferedBlockCipher cipher)
|
||||
{
|
||||
this.agree = agree;
|
||||
this.kdf = kdf;
|
||||
this.mac = mac;
|
||||
macBuf = new byte[mac.GetMacSize()];
|
||||
this.cipher = cipher;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters privParameters, ICipherParameters pubParameters, ICipherParameters iesParameters)
|
||||
{
|
||||
this.forEncryption = forEncryption;
|
||||
privParam = privParameters;
|
||||
pubParam = pubParameters;
|
||||
param = (IesParameters)iesParameters;
|
||||
}
|
||||
|
||||
private byte[] DecryptBlock(byte[] in_enc, int inOff, int inLen, byte[] z)
|
||||
{
|
||||
byte[] array = null;
|
||||
KeyParameter keyParameter = null;
|
||||
KdfParameters kdfParameters = new KdfParameters(z, param.GetDerivationV());
|
||||
int macKeySize = param.MacKeySize;
|
||||
kdf.Init(kdfParameters);
|
||||
if (inLen < mac.GetMacSize())
|
||||
{
|
||||
throw new InvalidCipherTextException("Length of input must be greater than the MAC");
|
||||
}
|
||||
inLen -= mac.GetMacSize();
|
||||
if (cipher == null)
|
||||
{
|
||||
byte[] array2 = GenerateKdfBytes(kdfParameters, inLen + macKeySize / 8);
|
||||
array = new byte[inLen];
|
||||
for (int i = 0; i != inLen; i++)
|
||||
{
|
||||
array[i] = (byte)(in_enc[inOff + i] ^ array2[i]);
|
||||
}
|
||||
keyParameter = new KeyParameter(array2, inLen, macKeySize / 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize;
|
||||
byte[] key = GenerateKdfBytes(kdfParameters, cipherKeySize / 8 + macKeySize / 8);
|
||||
cipher.Init(forEncryption: false, new KeyParameter(key, 0, cipherKeySize / 8));
|
||||
array = cipher.DoFinal(in_enc, inOff, inLen);
|
||||
keyParameter = new KeyParameter(key, cipherKeySize / 8, macKeySize / 8);
|
||||
}
|
||||
byte[] encodingV = param.GetEncodingV();
|
||||
mac.Init(keyParameter);
|
||||
mac.BlockUpdate(in_enc, inOff, inLen);
|
||||
mac.BlockUpdate(encodingV, 0, encodingV.Length);
|
||||
mac.DoFinal(macBuf, 0);
|
||||
inOff += inLen;
|
||||
byte[] a = Arrays.CopyOfRange(in_enc, inOff, inOff + macBuf.Length);
|
||||
if (!Arrays.ConstantTimeAreEqual(a, macBuf))
|
||||
{
|
||||
throw new InvalidCipherTextException("Invalid MAC.");
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private byte[] EncryptBlock(byte[] input, int inOff, int inLen, byte[] z)
|
||||
{
|
||||
byte[] array = null;
|
||||
KeyParameter keyParameter = null;
|
||||
KdfParameters kParam = new KdfParameters(z, param.GetDerivationV());
|
||||
int num = 0;
|
||||
int macKeySize = param.MacKeySize;
|
||||
if (cipher == null)
|
||||
{
|
||||
byte[] array2 = GenerateKdfBytes(kParam, inLen + macKeySize / 8);
|
||||
array = new byte[inLen + mac.GetMacSize()];
|
||||
num = inLen;
|
||||
for (int i = 0; i != inLen; i++)
|
||||
{
|
||||
array[i] = (byte)(input[inOff + i] ^ array2[i]);
|
||||
}
|
||||
keyParameter = new KeyParameter(array2, inLen, macKeySize / 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize;
|
||||
byte[] key = GenerateKdfBytes(kParam, cipherKeySize / 8 + macKeySize / 8);
|
||||
cipher.Init(forEncryption: true, new KeyParameter(key, 0, cipherKeySize / 8));
|
||||
num = cipher.GetOutputSize(inLen);
|
||||
byte[] array3 = new byte[num];
|
||||
int num2 = cipher.ProcessBytes(input, inOff, inLen, array3, 0);
|
||||
num2 += cipher.DoFinal(array3, num2);
|
||||
array = new byte[num2 + mac.GetMacSize()];
|
||||
num = num2;
|
||||
Array.Copy(array3, 0, array, 0, num2);
|
||||
keyParameter = new KeyParameter(key, cipherKeySize / 8, macKeySize / 8);
|
||||
}
|
||||
byte[] encodingV = param.GetEncodingV();
|
||||
mac.Init(keyParameter);
|
||||
mac.BlockUpdate(array, 0, num);
|
||||
mac.BlockUpdate(encodingV, 0, encodingV.Length);
|
||||
mac.DoFinal(array, num);
|
||||
return array;
|
||||
}
|
||||
|
||||
private byte[] GenerateKdfBytes(KdfParameters kParam, int length)
|
||||
{
|
||||
byte[] array = new byte[length];
|
||||
kdf.Init(kParam);
|
||||
kdf.GenerateBytes(array, 0, array.Length);
|
||||
return array;
|
||||
}
|
||||
|
||||
public virtual byte[] ProcessBlock(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
agree.Init(privParam);
|
||||
BigInteger n = agree.CalculateAgreement(pubParam);
|
||||
byte[] array = BigIntegers.AsUnsignedByteArray(agree.GetFieldSize(), n);
|
||||
try
|
||||
{
|
||||
return forEncryption ? EncryptBlock(input, inOff, inLen, array) : DecryptBlock(input, inOff, inLen, array);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Array.Clear(array, 0, array.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class IsaacEngine : IStreamCipher
|
||||
{
|
||||
private static readonly int sizeL = 8;
|
||||
|
||||
private static readonly int stateArraySize = sizeL << 5;
|
||||
|
||||
private uint[] engineState = null;
|
||||
|
||||
private uint[] results = null;
|
||||
|
||||
private uint a = 0u;
|
||||
|
||||
private uint b = 0u;
|
||||
|
||||
private uint c = 0u;
|
||||
|
||||
private int index = 0;
|
||||
|
||||
private byte[] keyStream = new byte[stateArraySize << 2];
|
||||
|
||||
private byte[] workingKey = null;
|
||||
|
||||
private bool initialised = false;
|
||||
|
||||
public virtual string AlgorithmName => "ISAAC";
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is KeyParameter))
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to ISAAC Init - " + Platform.GetTypeName(parameters), "parameters");
|
||||
}
|
||||
KeyParameter keyParameter = (KeyParameter)parameters;
|
||||
setKey(keyParameter.GetKey());
|
||||
}
|
||||
|
||||
public virtual byte ReturnByte(byte input)
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
isaac();
|
||||
keyStream = Pack.UInt32_To_BE(results);
|
||||
}
|
||||
byte result = (byte)(keyStream[index] ^ input);
|
||||
index = (index + 1) & 0x3FF;
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual void ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
|
||||
{
|
||||
if (!initialised)
|
||||
{
|
||||
throw new InvalidOperationException(AlgorithmName + " not initialised");
|
||||
}
|
||||
Check.DataLength(input, inOff, len, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, len, "output buffer too short");
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
isaac();
|
||||
keyStream = Pack.UInt32_To_BE(results);
|
||||
}
|
||||
output[i + outOff] = (byte)(keyStream[index] ^ input[i + inOff]);
|
||||
index = (index + 1) & 0x3FF;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
setKey(workingKey);
|
||||
}
|
||||
|
||||
private void setKey(byte[] keyBytes)
|
||||
{
|
||||
workingKey = keyBytes;
|
||||
if (engineState == null)
|
||||
{
|
||||
engineState = new uint[stateArraySize];
|
||||
}
|
||||
if (results == null)
|
||||
{
|
||||
results = new uint[stateArraySize];
|
||||
}
|
||||
for (int i = 0; i < stateArraySize; i++)
|
||||
{
|
||||
engineState[i] = (results[i] = 0u);
|
||||
}
|
||||
a = (b = (c = 0u));
|
||||
index = 0;
|
||||
byte[] array = new byte[keyBytes.Length + (keyBytes.Length & 3)];
|
||||
Array.Copy(keyBytes, 0, array, 0, keyBytes.Length);
|
||||
for (int i = 0; i < array.Length; i += 4)
|
||||
{
|
||||
results[i >> 2] = Pack.LE_To_UInt32(array, i);
|
||||
}
|
||||
uint[] array2 = new uint[sizeL];
|
||||
for (int i = 0; i < sizeL; i++)
|
||||
{
|
||||
array2[i] = 2654435769u;
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
mix(array2);
|
||||
}
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int j = 0; j < stateArraySize; j += sizeL)
|
||||
{
|
||||
for (int k = 0; k < sizeL; k++)
|
||||
{
|
||||
uint[] array4;
|
||||
uint[] array3 = (array4 = array2);
|
||||
int num = k;
|
||||
nint num2 = num;
|
||||
array3[num] = array4[num2] + ((i < 1) ? results[j + k] : engineState[j + k]);
|
||||
}
|
||||
mix(array2);
|
||||
for (int k = 0; k < sizeL; k++)
|
||||
{
|
||||
engineState[j + k] = array2[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
isaac();
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
private void isaac()
|
||||
{
|
||||
b += ++c;
|
||||
for (int i = 0; i < stateArraySize; i++)
|
||||
{
|
||||
uint num = engineState[i];
|
||||
switch (i & 3)
|
||||
{
|
||||
case 0:
|
||||
a ^= a << 13;
|
||||
break;
|
||||
case 1:
|
||||
a ^= a >> 6;
|
||||
break;
|
||||
case 2:
|
||||
a ^= a << 2;
|
||||
break;
|
||||
case 3:
|
||||
a ^= a >> 16;
|
||||
break;
|
||||
}
|
||||
a += engineState[(i + 128) & 0xFF];
|
||||
uint num2 = (engineState[i] = engineState[(num >> 2) & 0xFF] + a + b);
|
||||
results[i] = (b = engineState[(num2 >> 10) & 0xFF] + num);
|
||||
}
|
||||
}
|
||||
|
||||
private void mix(uint[] x)
|
||||
{
|
||||
uint[] array;
|
||||
(array = x)[0] = array[0] ^ (x[1] << 11);
|
||||
(array = x)[3] = array[3] + x[0];
|
||||
(array = x)[1] = array[1] + x[2];
|
||||
(array = x)[1] = array[1] ^ (x[2] >> 2);
|
||||
(array = x)[4] = array[4] + x[1];
|
||||
(array = x)[2] = array[2] + x[3];
|
||||
(array = x)[2] = array[2] ^ (x[3] << 8);
|
||||
(array = x)[5] = array[5] + x[2];
|
||||
(array = x)[3] = array[3] + x[4];
|
||||
(array = x)[3] = array[3] ^ (x[4] >> 16);
|
||||
(array = x)[6] = array[6] + x[3];
|
||||
(array = x)[4] = array[4] + x[5];
|
||||
(array = x)[4] = array[4] ^ (x[5] << 10);
|
||||
(array = x)[7] = array[7] + x[4];
|
||||
(array = x)[5] = array[5] + x[6];
|
||||
(array = x)[5] = array[5] ^ (x[6] >> 4);
|
||||
(array = x)[0] = array[0] + x[5];
|
||||
(array = x)[6] = array[6] + x[7];
|
||||
(array = x)[6] = array[6] ^ (x[7] << 8);
|
||||
(array = x)[1] = array[1] + x[6];
|
||||
(array = x)[7] = array[7] + x[0];
|
||||
(array = x)[7] = array[7] ^ (x[0] >> 9);
|
||||
(array = x)[2] = array[2] + x[7];
|
||||
(array = x)[0] = array[0] + x[1];
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user