public static void crypto_sign_prehashed( byte[] sig, byte[] m, int mlen, byte[] sk, byte[] pk ) { byte[] r, hram; GroupElementP3 R; var hasher = new Sha512(); { hasher.Init(); hasher.Update(sk, 32, 32); hasher.Update(m, 0, mlen); r = hasher.Finalize(); ScalarOperations.sc_reduce(r); GroupOperations.ge_scalarmult_base(out R, r, 0); GroupOperations.ge_p3_tobytes(sig, 0, ref R); hasher.Init(); hasher.Update(sig, 0, 32); hasher.Update(pk, 0, 32); hasher.Update(m, 0, mlen); hram = hasher.Finalize(); ScalarOperations.sc_reduce(hram); var s = new byte[32]; //todo: remove allocation Array.Copy(sig, 32, s, 0, 32); ScalarOperations.sc_muladd(s, hram, sk, r); Array.Copy(s, 0, sig, 32, 32); CryptoBytes.Wipe(s); } }
public static void CryptoSign( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] sk, int skoffset) { var hasher = new Sha512(); { hasher.Update(sk, skoffset, 32); var az = hasher.Finalize(); ScalarOperations.Clamp(az, 0); hasher.Init(); hasher.Update(az, 32, 32); hasher.Update(m, moffset, mlen); var r = hasher.Finalize(); ScalarOperations.Reduce(r); GroupElementP3 R; GroupOperations.ScalarMultBase(out R, r, 0); GroupOperations.P3ToBytes(sig, sigoffset, ref R); hasher.Init(); hasher.Update(sig, sigoffset, 32); hasher.Update(sk, skoffset + 32, 32); hasher.Update(m, moffset, mlen); var hram = hasher.Finalize(); ScalarOperations.Reduce(hram); var s = new byte[32]; Array.Copy(sig, sigoffset + 32, s, 0, 32); ScalarOperations.MulAdd(s, hram, az, r); Array.Copy(s, 0, sig, sigoffset + 32, 32); CryptoBytes.Wipe(s); } }
public void Sha512_Split() { // use only a subset of possible indices to speed up the test var indices = Enumerable.Range(0, 300).Where(i => (i % 64) < 5 || (i % 64) > 64 - 5).ToArray(); var sha512Framework = new SHA512Managed(); foreach (var k in indices) { foreach (var m in indices) { foreach (var n in indices) { var message = Enumerable.Range(1, k + m + n).Select(i => (byte)i).ToArray(); var hashExpected = sha512Framework.ComputeHash(message); var hasher = new Sha512(); hasher.Update(message, 0, k); hasher.Update(message, k, m); hasher.Update(message, k + m, n); var hash = hasher.Finalize(); TestHelpers.AssertEqualBytes(hashExpected, hash); } } } }
// 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 hasher = new Sha512(); hasher.Update(sig, sigoffset, 32); hasher.Update(pk, pkoffset, 32); hasher.Update(m, moffset, mlen); h = hasher.Finalize(); 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; }
public void Sha512_Reuse() { var message = Enumerable.Range(1, 100).Select(i => (byte)i).ToArray(); var sha512Framework = new SHA512Managed(); var hashExpected = sha512Framework.ComputeHash(message); var hasher = new Sha512(); hasher.Update(message, 0, message.Length); var hash1 = hasher.Finalize(); TestHelpers.AssertEqualBytes(hashExpected, hash1); hasher.Init(); hasher.Update(message, 0, message.Length); var hash2 = hasher.Finalize(); TestHelpers.AssertEqualBytes(hashExpected, hash2); }
public void Sha512OutputSegments() { var message = new[] { (byte)'a', (byte)'b', (byte)'c' }; var hashExpected = _sha512HashAbc; var sha512 = new Sha512(); sha512.Update(message, 0, message.Length); var output = new byte[64].Pad(); sha512.Finalize(output); TestHelpers.AssertEqualBytes(hashExpected, output.UnPad()); }
public static void crypto_sign_private_prehash(byte[] sk, byte[] prehashedSk) { var prehashed = new byte[64]; Array.Copy(sk, prehashed, 64); var hasher = new Sha512(); hasher.Update(sk, 0, 64); var h = hasher.Finalize(); ScalarOperations.sc_clamp(h, 0); Array.Copy(h, prehashed, 32); Array.Copy(prehashed, prehashedSk, 64); }
public static void crypto_sign( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] sk, int skoffset) { byte[] az, r, hram; GroupElementP3 R; var hasher = new Sha512(); { hasher.Update(sk, skoffset, 32); az = hasher.Finalize(); ScalarOperations.sc_clamp(az, 0); hasher.Init(); hasher.Update(az, 32, 32); hasher.Update(m, moffset, mlen); r = hasher.Finalize(); 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.Finalize(); 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 void crypto_sign( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] sk, int skoffset) { byte[] az, r, hram; GroupElementP3 R; var hasher = new Sha512(); { hasher.Update(sk, skoffset, 32); az = hasher.Finalize(); ScalarOperations.sc_clamp(az, 0); hasher.Init(); hasher.Update(az, 32, 32); hasher.Update(m, moffset, mlen); r = hasher.Finalize(); 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.Finalize(); 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 void Sha512_Split() { // use only a subset of possible indices to speed up the test var indices = Enumerable.Range(0, 300).Where(i => (i % 64) < 5 || (i % 64) > 64 - 5).ToArray(); var sha512Framework = new SHA512Managed(); foreach (var k in indices) foreach (var m in indices) foreach (var n in indices) { var message = Enumerable.Range(1, k + m + n).Select(i => (byte)i).ToArray(); var hashExpected = sha512Framework.ComputeHash(message); var hasher = new Sha512(); hasher.Update(message, 0, k); hasher.Update(message, k, m); hasher.Update(message, k + m, n); var hash = hasher.Finalize(); TestHelpers.AssertEqualBytes(hashExpected, hash); } }
// 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 hasher = new Sha512(); hasher.Update(sig, sigoffset, 32); hasher.Update(pk, pkoffset, 32); hasher.Update(m, moffset, mlen); h = hasher.Finalize(); 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); }
public static bool CryptoSignVerify( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] pk, int pkoffset) { var checker = new byte[32]; GroupElementP3 A; GroupElementP2 R; if ((sig[sigoffset + 63] & 224) != 0) { return(false); } if (GroupOperations.FromBytes(out A, pk, pkoffset) != 0) { return(false); } var hasher = new Sha512(); hasher.Update(sig, sigoffset, 32); hasher.Update(pk, pkoffset, 32); hasher.Update(m, moffset, mlen); var h = hasher.Finalize(); ScalarOperations.Reduce(h); var sm32 = new byte[32]; Array.Copy(sig, sigoffset + 32, sm32, 0, 32); GroupOperations.DoubleScalarMult(out R, h, ref A, sm32); GroupOperations.ToBytes(checker, 0, ref R); var result = CryptoBytes.ConstantTimeEquals(checker, 0, sig, sigoffset, 32); CryptoBytes.Wipe(h); CryptoBytes.Wipe(checker); return(result); }
public void Sha512OutputSegmentsIncorretOutputSize() { var sha512 = new Sha512(); sha512.Finalize(new byte[32].Pad()); }
public void Sha512OutputSegmentsNull() { var sha512 = new Sha512(); sha512.Finalize(default(ArraySegment <byte>)); }
public void Sha512OutputSegmentsNull() { var sha512 = new Sha512(); sha512.Finalize(default(ArraySegment<byte>)); }