public void Decrypt() { try { if (Constants.IsRc4) { Client.Decrypt(m_vData); if (m_vType == 10101) { Client.State = ClientState.Login; } // No need since the decryption occurs on same buffer. //SetData(m_vData); } else { if (m_vType == 10101) { var cipherText = m_vData; Client.CPublicKey = cipherText.Take(32).ToArray(); var blake = Blake2B.Create(new Blake2BConfig { OutputSizeInBytes = 24 }); blake.Init(); blake.Update(Client.CPublicKey); blake.Update(Key.Crypto.PublicKey); Client.CRNonce = blake.Finish(); cipherText = CustomNaCl.OpenPublicBox(cipherText.Skip(32).ToArray(), Client.CRNonce, Key.Crypto.PrivateKey, Client.CPublicKey); Client.CSharedKey = Client.CPublicKey; Client.CSessionKey = cipherText.Take(24).ToArray(); Client.CSNonce = cipherText.Skip(24).Take(24).ToArray(); Client.State = ClientState.Login; SetData(cipherText.Skip(48).ToArray()); } else { if (m_vType != 10100) { if (Client.State == ClientState.LoginSuccess) { Client.CSNonce.Increment(); SetData(CustomNaCl.OpenSecretBox(new byte[16].Concat(m_vData).ToArray(), Client.CSNonce, Client.CSharedKey)); } } } } } catch { Client.State = ClientState.Exception; throw; } }
public static void crypto_sign_keypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset) { GroupElementP3 A; int i; Array.Copy(seed, seedoffset, sk, skoffset, 32); var blake2bConfig = new Blake2BConfig { OutputSizeInBytes = 64 }; var hasher = Blake2B.Create(blake2bConfig); hasher.Update(sk, skoffset, 32); byte[] h = hasher.Finish(); //byte[] h = Sha512.Hash(sk, skoffset, 32);//ToDo: Remove alloc ScalarOperations.sc_clamp(h, 0); GroupOperations.ge_scalarmult_base(out A, h, 0); GroupOperations.ge_p3_tobytes(pk, pkoffset, ref A); for (i = 0; i < 32; ++i) { sk[skoffset + 32 + i] = pk[pkoffset + i]; } CryptoBytes.Wipe(h); }
public void Decrypt() { try { if (m_vType == 10101) { byte[] cipherText = m_vData; Client.CPublicKey = cipherText.Take(32).ToArray(); Hasher b = Blake2B.Create(new Blake2BConfig { OutputSizeInBytes = 24 }); b.Init(); b.Update(Client.CPublicKey); b.Update(Key.Crypto.PublicKey); Client.CRNonce = b.Finish(); cipherText = CustomNaCl.OpenPublicBox(cipherText.Skip(32).ToArray(), Client.CRNonce, Key.Crypto.PrivateKey, Client.CPublicKey); Client.CSharedKey = Client.CPublicKey; Client.CSessionKey = cipherText.Take(24).ToArray(); Client.CSNonce = cipherText.Skip(24).Take(24).ToArray(); Client.CState = 1; SetData(cipherText.Skip(48).ToArray()); } else if (m_vType != 10100) { Client.CSNonce.Increment(); SetData(CustomNaCl.OpenSecretBox(new byte[16].Concat(m_vData).ToArray(), Client.CSNonce, Client.CSharedKey)); } } catch (Exception ex) { Client.CState = 0; } }
public string EncodeAccount(UInt256 account) { var hasher = Blake2B.Create(new Blake2BConfig { OutputSizeInBytes = 5 }); var bytes = account.ToByteArray().Reverse().ToArray(); hasher.Update(bytes); byte[] checkBytes = hasher.Finish(); Array.Resize(ref checkBytes, 8); UInt64 check = BitConverter.ToUInt64(checkBytes, 0); BigInteger number = Number(bytes); number <<= 40; number |= new BigInteger(check); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 60; i++) { var r = number.ToByteArray()[0] & 0x1f; number >>= 5; sb.Append(AccountLookup[r]); } sb.Append("_brx"); var addrReverse = sb.ToString(); var arr = addrReverse.ToCharArray(); Array.Reverse(arr); return(new string(arr)); }
public void Encrypt(byte[] plainText) { try { if (GetMessageType() == 20104 || GetMessageType() == 20103) { Hasher b = Blake2B.Create(new Blake2BConfig { OutputSizeInBytes = 24 }); b.Init(); b.Update(Client.CSNonce); b.Update(Client.CPublicKey); b.Update(Key.Crypto.PublicKey); SetData(CustomNaCl.CreatePublicBox(Client.CRNonce.Concat(Client.CSharedKey).Concat(plainText).ToArray(), b.Finish(), Key.Crypto.PrivateKey, Client.CPublicKey)); if (GetMessageType() == 20104) { Client.CState = 2; } } else { Client.CRNonce.Increment(); SetData(CustomNaCl.CreateSecretBox(plainText, Client.CRNonce, Client.CSharedKey).Skip(16).ToArray()); } } catch (Exception) { Client.CState = 0; } }
public bool ValidateAddress(string address) { if (address.Length != 64 && !address.StartsWith("xrb_")) { return(false); } var pk32 = address.Substring(4, 52); var pk = Base32withPadding.Decode(pk32, _base32Alphabet, 4); var checksum = address.Substring(56); var checksumDecoded = Base32withPadding.Decode(checksum, _base32Alphabet, 0); checksumDecoded = checksumDecoded.Reverse().ToArray(); var blake2bConfig = new Blake2BConfig { OutputSizeInBytes = 5 }; var hasher = Blake2B.Create(blake2bConfig); hasher.Update(pk); var pkChecksum = hasher.Finish(); return(pkChecksum.SequenceEqual(checksumDecoded)); }
public static string HashStateBlock(string accountAddress, string previousHash, string balance, string representativeAccount, string link) { var representativePublicKey = AddressToPublicKey(representativeAccount); var accountPublicKey = AddressToPublicKey(accountAddress); var previousBytes = HexStringToByteArray(previousHash); var balanceHex = BigInteger.Parse(balance).ToString("X"); if (balanceHex.Length % 2 == 1) { balanceHex = "0" + balanceHex; } byte[] balanceBytes = HexStringToByteArray(balanceHex.PadLeft(32, '0')); var linkBytes = HexStringToByteArray(link); var preamble = HexStringToByteArray("0000000000000000000000000000000000000000000000000000000000000006"); var blake = Blake2B.Create(new Blake2BConfig() { OutputSizeInBytes = 32 }); blake.Init(); blake.Update(preamble); blake.Update(accountPublicKey); blake.Update(previousBytes); blake.Update(representativePublicKey); blake.Update(balanceBytes); blake.Update(linkBytes); var hashBytes = blake.Finish(); return(ByteArrayToHex(hashBytes)); }
public void Hash(Blake2BConfig config, byte[] message) { var hasher = Blake2B.Create(new Blake2BConfig() { OutputSizeInBytes = 64 }); hasher.Init(); hasher.Update(Previous.ToByteArray()); hasher.Update(Source.ToByteArray()); }
public static byte[] Hash(byte[] data, int size) { var hasher = Blake2B.Create(new Blake2BConfig { OutputSizeInBytes = size, }); hasher.Init(); hasher.Update(data); return(hasher.Finish()); }
public void Hash(Blake2BConfig config, byte[] message) { var hasher = Blake2B.Create(new Blake2BConfig() { OutputSizeInBytes = 64 }); hasher.Init(); hasher.Update(Source.ToByteArray()); hasher.Update(Representative.ToByteArray()); hasher.Update(Account.ToByteArray()); }
// Original crypto_sign_open, for reference only /*public static int crypto_sign_open( * byte[] m, out int mlen, * byte[] sm, int smlen, * byte[] pk) * { * byte[] h = new byte[64]; * byte[] checkr = new byte[32]; * GroupElementP3 A; * GroupElementP2 R; * int i; * * mlen = -1; * if (smlen < 64) return -1; * if ((sm[63] & 224) != 0) return -1; * if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, 0) != 0) return -1; * * for (i = 0; i < smlen; ++i) m[i] = sm[i]; * for (i = 0; i < 32; ++i) m[32 + i] = pk[i]; * Sha512BclWrapper.crypto_hash_sha512(h, m, 0, smlen); * ScalarOperations.sc_reduce(h); * * var sm32 = new byte[32]; * Array.Copy(sm, 32, sm32, 0, 32); * GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32); * GroupOperations.ge_tobytes(checkr, 0, ref R); * if (Helpers.crypto_verify_32(checkr, sm) != 0) * { * for (i = 0; i < smlen; ++i) * m[i] = 0; * return -1; * } * * for (i = 0; i < smlen - 64; ++i) * m[i] = sm[64 + i]; * for (i = smlen - 64; i < smlen; ++i) * m[i] = 0; * mlen = smlen - 64; * return 0; * }*/ public static bool crypto_sign_verify( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] pk, int pkoffset) { byte[] h; byte[] checkr = new byte[32]; GroupElementP3 A; GroupElementP2 R; if ((sig[sigoffset + 63] & 224) != 0) { return(false); } if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, pkoffset) != 0) { return(false); } var blake2bConfig = new Blake2BConfig { OutputSizeInBytes = 64 }; var hasher = Blake2B.Create(blake2bConfig); hasher.Update(sig, sigoffset, 32); hasher.Update(pk, pkoffset, 32); hasher.Update(m, moffset, mlen); h = hasher.Finish(); /* * var hasher = new Sha512(); * hasher.Update(sig, sigoffset, 32); * hasher.Update(pk, pkoffset, 32); * hasher.Update(m, moffset, mlen); * h = hasher.Finish(); */ ScalarOperations.sc_reduce(h); var sm32 = new byte[32];//todo: remove allocation Array.Copy(sig, sigoffset + 32, sm32, 0, 32); GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32); GroupOperations.ge_tobytes(checkr, 0, ref R); var result = CryptoBytes.ConstantTimeEquals(checkr, 0, sig, sigoffset, 32); CryptoBytes.Wipe(h); CryptoBytes.Wipe(checkr); return(result); }
byte[] GenerateRaiAddressSeed(int index) { var blake2bConfig = new Blake2BConfig { OutputSizeInBytes = 32 }; var hasher = Blake2B.Create(blake2bConfig); hasher.Update(Seed); var indexBytes = BitConverter.GetBytes(index).Reverse().ToArray(); hasher.Update(indexBytes); return(hasher.Finish()); }
public static byte[] HashAll(params byte[][] data) { var hasher = Blake2B.Create(new Blake2BConfig() { OutputSizeInBytes = 32 }, SecureArray.DefaultCall); foreach (var d in data) { hasher.Update(d); } var hashAll = hasher.Finish(); return(hashAll); }
public static void KeyExchange(ArraySegment <byte> sharedKey, ArraySegment <byte> publicKey, ArraySegment <byte> privateKey) { if (sharedKey.Array == null) { throw new ArgumentNullException("sharedKey.Array"); } if (publicKey.Array == null) { throw new ArgumentNullException("publicKey.Array"); } if (privateKey.Array == null) { throw new ArgumentNullException("privateKey"); } if (sharedKey.Count != 32) { throw new ArgumentException("sharedKey.Count != 32"); } if (publicKey.Count != 32) { throw new ArgumentException("publicKey.Count != 32"); } if (privateKey.Count != 64) { throw new ArgumentException("privateKey.Count != 64"); } FieldElement montgomeryX, edwardsY, edwardsZ, sharedMontgomeryX; FieldOperations.fe_frombytes(out edwardsY, publicKey.Array, publicKey.Offset); FieldOperations.fe_1(out edwardsZ); MontgomeryCurve25519.EdwardsToMontgomeryX(out montgomeryX, ref edwardsY, ref edwardsZ); var blake2bConfig = new Blake2BConfig { OutputSizeInBytes = 64 }; var hasher = Blake2B.Create(blake2bConfig); hasher.Update(privateKey.Array, privateKey.Offset, 32); byte[] h = hasher.Finish(); //byte[] h = Sha512.Hash(privateKey.Array, privateKey.Offset, 32);//ToDo: Remove alloc ScalarOperations.sc_clamp(h, 0); MontgomeryOperations.scalarmult(out sharedMontgomeryX, h, 0, ref montgomeryX); CryptoBytes.Wipe(h); FieldOperations.fe_tobytes(sharedKey.Array, sharedKey.Offset, ref sharedMontgomeryX); MontgomeryCurve25519.KeyExchangeOutputHashNaCl(sharedKey.Array, sharedKey.Offset); }
public UInt256 DecodeAccount(string account) { if (account.Length != 64) { throw new InvalidDataException("length should be 64"); } if (!account.StartsWith("xrb_")) { throw new InvalidDataException("invalid account format"); } BigInteger number = new BigInteger(); for (int i = 4; i < account.Length; i++) { sbyte byteResult = DecodeChar(account[i]); if (byteResult != '~') { number <<= 5; number += byteResult; } } UInt256 accountUInt256 = new UInt256(number >> 40); var accountBytes = accountUInt256.ToByteArray().Reverse().ToArray(); UInt64 check = BitConverter.ToUInt64(number.ToByteArray(), 0); check &= 0xffffffffff; var hasher = Blake2B.Create(new Blake2BConfig { OutputSizeInBytes = 5 }); hasher.Update(accountBytes); var final = hasher.Finish(); Array.Resize(ref final, 8); UInt64 validation = BitConverter.ToUInt64(final, 0); if (check != validation) { throw new InvalidDataException(); } return(accountUInt256); }
public static string PublicKeyToAddress(byte[] publicKey) { var address = "nano_" + NanoEncode(publicKey); var blake = Blake2B.Create(new Blake2BConfig() { OutputSizeInBytes = 5 }); blake.Init(); blake.Update(publicKey); var checksumBytes = blake.Finish(); address += NanoEncode(checksumBytes.Reverse().ToArray(), false); return(address); }
/// <summary> /// Does a Blake2 hash with the ability to truncate or extend the hash to any length. /// </summary> /// <param name="hash"> /// The buffer to fill with the hash. /// </param> /// <param name="inputBuffer"> /// What to hash. /// </param> /// <param name="secureArrayCall"> /// The methods that get called to secure arrays. A null value defaults to <see cref="SecureArray"/>.<see cref="SecureArray.DefaultCall"/>. /// </param> private static void Blake2BLong(byte[] hash, byte[] inputBuffer, SecureArrayCall secureArrayCall) { var outputLengthBytes = new byte[4]; using var intermediateHash = SecureArray <byte> .Best(Blake2B.OutputLength, secureArrayCall); var config = new Blake2BConfig { Result64ByteBuffer = intermediateHash.Buffer, OutputSizeInBytes = hash.Length > 64 ? 64 : hash.Length, }; Store32(outputLengthBytes, hash.Length); using (var blakeHash = Blake2B.Create(config, secureArrayCall)) { blakeHash.Update(outputLengthBytes); blakeHash.Update(inputBuffer); blakeHash.Finish(); } if (hash.Length <= intermediateHash.Buffer.Length) { Array.Copy(intermediateHash.Buffer, hash, hash.Length); return; } const int b2B2 = Blake2B.OutputLength / 2; Array.Copy(intermediateHash.Buffer, hash, b2B2); int pos = b2B2; int lastHashIndex = hash.Length - Blake2B.OutputLength; var toHash = new byte[Blake2B.OutputLength]; while (pos < lastHashIndex) { Array.Copy(intermediateHash.Buffer, toHash, intermediateHash.Buffer.Length); Blake2B.ComputeHash(toHash, config, secureArrayCall); Array.Copy(intermediateHash.Buffer, 0, hash, pos, b2B2); pos += b2B2; } Array.Copy(intermediateHash.Buffer, toHash, intermediateHash.Buffer.Length); Blake2B.ComputeHash(toHash, config, secureArrayCall); Array.Copy(intermediateHash.Buffer, 0, hash, pos, hash.Length - pos); }
public void Encrypt(byte[] plainText) { try { if (Constants.IsRc4) { Client.Encrypt(plainText); if (m_vType == 20104) { Client.State = Client.ClientState.LoginSuccess; } SetData(plainText); } else { if (m_vType == 20104 || m_vType == 20103) { Hasher b = Blake2B.Create(new Blake2BConfig { OutputSizeInBytes = 24 }); b.Init(); b.Update(Client.CSNonce); b.Update(Client.CPublicKey); b.Update(Key.Crypto.PublicKey); SetData(CustomNaCl.CreatePublicBox(Client.CRNonce.Concat(Client.CSharedKey).Concat(plainText).ToArray(), b.Finish(), Key.Crypto.PrivateKey, Client.CPublicKey)); if (m_vType == 20104) { Client.State = Client.ClientState.LoginSuccess; } } else { Client.CRNonce.Increment(); SetData(CustomNaCl.CreateSecretBox(plainText, Client.CRNonce, Client.CSharedKey).Skip(16).ToArray()); } } } catch (Exception) { Client.State = ClientState.Exception; } }
public string PublicAddress(int index = 0) { var addressSeed = GenerateRaiAddressSeed(index); var pk = Ed25519.PublicKeyFromSeed(addressSeed); var pk32 = Base32withPadding.Encode(pk, _base32Alphabet, 260); var blake2bConfig = new Blake2BConfig { OutputSizeInBytes = 5 }; var hasher = Blake2B.Create(blake2bConfig); hasher.Update(pk); var checksum = hasher.Finish().Reverse().ToArray(); var checksum32 = Base32withPadding.Encode(checksum, _base32Alphabet, 40); return($"xrb_{pk32}{checksum32}"); }
/*public static void crypto_sign( * byte[] sm, out int smlen, * byte[] m, int mlen, * byte[] sk * ) * { * byte[] az = new byte[64]; * byte[] r = new byte[64]; * byte[] hram = new byte[64]; * GroupElementP3 R; * int i; * * Helpers.crypto_hash_sha512(az, sk, 0, 32); * az[0] &= 248; * az[31] &= 63; * az[31] |= 64; * * smlen = mlen + 64; * for (i = 0; i < mlen; ++i) sm[64 + i] = m[i]; * for (i = 0; i < 32; ++i) sm[32 + i] = az[32 + i]; * Helpers.crypto_hash_sha512(r, sm, 32, mlen + 32); * for (i = 0; i < 32; ++i) sm[32 + i] = sk[32 + i]; * * ScalarOperations.sc_reduce(r); * GroupOperations.ge_scalarmult_base(out R, r, 0); * GroupOperations.ge_p3_tobytes(sm, 0, ref R); * * Helpers.crypto_hash_sha512(hram, sm, 0, mlen + 64); * ScalarOperations.sc_reduce(hram); * var sm32 = new byte[32]; * Array.Copy(sm, 32, sm32, 0, 32); * ScalarOperations.sc_muladd(sm32, hram, az, r); * Array.Copy(sm32, 0, sm, 32, 32); * }*/ public static void crypto_sign2( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] sk, int skoffset) { byte[] az; byte[] r; byte[] hram; GroupElementP3 R; var blake2bConfig = new Blake2BConfig { OutputSizeInBytes = 64 }; var hasher = Blake2B.Create(blake2bConfig); //var hasher = new Sha512(); { hasher.Update(sk, skoffset, 32); az = hasher.Finish(); ScalarOperations.sc_clamp(az, 0); hasher.Init(); hasher.Update(az, 32, 32); hasher.Update(m, moffset, mlen); r = hasher.Finish(); ScalarOperations.sc_reduce(r); GroupOperations.ge_scalarmult_base(out R, r, 0); GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R); hasher.Init(); hasher.Update(sig, sigoffset, 32); hasher.Update(sk, skoffset + 32, 32); hasher.Update(m, moffset, mlen); hram = hasher.Finish(); ScalarOperations.sc_reduce(hram); var s = new byte[32]; //todo: remove allocation Array.Copy(sig, sigoffset + 32, s, 0, 32); ScalarOperations.sc_muladd(s, hram, az, r); Array.Copy(s, 0, sig, sigoffset + 32, 32); CryptoBytes.Wipe(s); } }
public static bool AddressIsValid(string address) { byte[] pubkeyBytes = AddressToPublicKey(address); if (pubkeyBytes == null) { return(false); } var blake = Blake2B.Create(new Blake2BConfig() { OutputSizeInBytes = 5 }); blake.Init(); blake.Update(pubkeyBytes); var hashBytes = blake.Finish(); // Checksum is last 8 characters, compare var checksum = address.Substring(address.Length - 8, 8); var binaryString = ""; for (int i = 0; i < checksum.Length; i++) { // Decode each character into string representation of it's binary parts binaryString += nano_addressEncoding[checksum[i]]; } // Convert to bytes var pk = new byte[5]; for (int i = 0; i < 5; i++) { // for each byte, read the bits from the binary string var b = Convert.ToByte(binaryString.Substring(i * 8, 8), 2); pk[i] = b; } return(hashBytes.SequenceEqual(pk.Reverse())); }
public void Splits() { var hasher = Blake2B.Create(); for (int len = 0; len <= 256; len++) { hasher.Init(); hasher.Update(input, 0, len); string hash0 = BitConverter.ToString(hasher.Finish()); for (int split1 = 0; split1 <= len; split1++) { for (int split2 = split1; split2 <= len; split2++) { hasher.Init(); hasher.Update(input, 0, split1); hasher.Update(input, split1, split2 - split1); hasher.Update(input, split2, len - split2); string hash1 = BitConverter.ToString(hasher.Finish()); Assert.AreEqual(hash0, hash1); } } } }
private SecureArray <byte> InitialHash() { var ret = BestSecureArray <byte>(Blake2B.OutputLength); using (var blakeHash = Blake2B.Create( new Blake2BConfig { OutputSizeInBytes = PrehashDigestLength, Result64ByteBuffer = ret.Buffer })) { var value = new byte[4]; Store32(value, this.config.Lanes); blakeHash.Update(value); Store32(value, this.config.HashLength); blakeHash.Update(value); Store32(value, this.config.MemoryCost); blakeHash.Update(value); Store32(value, this.config.TimeCost); blakeHash.Update(value); Store32(value, (uint)this.config.Version); blakeHash.Update(value); Store32(value, (uint)this.config.Type); blakeHash.Update(value); Store32(value, this.config.Password?.Length ?? 0); blakeHash.Update(value); if (this.config.Password != null) { blakeHash.Update(this.config.Password); if (this.config.ClearPassword) { SecureArray.Zero(this.config.Password); } } Store32(value, this.config.Salt?.Length ?? 0); blakeHash.Update(value); if (this.config.Salt != null) { blakeHash.Update(this.config.Salt); } Store32(value, this.config.Secret?.Length ?? 0); blakeHash.Update(value); if (this.config.Secret != null) { blakeHash.Update(this.config.Secret); if (this.config.ClearSecret) { SecureArray.Zero(this.config.Secret); } } Store32(value, this.config.AssociatedData?.Length ?? 0); blakeHash.Update(value); if (this.config.AssociatedData != null) { blakeHash.Update(this.config.AssociatedData); } blakeHash.Finish(); } return(ret); }