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 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) { var hasher = new Sha512(); { hasher.Update(sk, skoffset, 32); var az = hasher.Finish(); stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.ScalarOperations.ScClamp(az, 0); hasher.Init(); hasher.Update(az, 32, 32); hasher.Update(m, moffset, mlen); var r = hasher.Finish(); stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.ScalarOperations.ScReduce(r); GroupElementP3 R; stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.GeScalarmultBase(out R, r, 0); stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.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); var hram = hasher.Finish(); stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.ScalarOperations.ScReduce(hram); var s = new byte[32]; Array.Copy(sig, sigoffset + 32, s, 0, 32); stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.ScalarOperations.ScMulAdd(s, hram, az, r); Array.Copy(s, 0, sig, sigoffset + 32, 32); CryptoBytes.Wipe(s); } }
public static void crypto_sign2(Span <byte> sig, ReadOnlySpan <byte> m, ReadOnlySpan <byte> sk) { var hasher = new Sha512(); { hasher.Update(sk.Slice(0, 32)); Span <byte> az = stackalloc byte[64]; hasher.Finish(az); ScalarOperations.sc_clamp(az); hasher.Init(); hasher.Update(az.Slice(32, 32)); hasher.Update(m); Span <byte> r = stackalloc byte[64]; hasher.Finish(r); ScalarOperations.sc_reduce(r); GroupOperations.ge_scalarmult_base(out var R, r); GroupOperations.ge_p3_tobytes(sig, in R); hasher.Init(); hasher.Update(sig.Slice(0, 32)); hasher.Update(sk.Slice(32, 32)); hasher.Update(m); Span <byte> hram = stackalloc byte[64]; hasher.Finish(hram); ScalarOperations.sc_reduce(hram); ScalarOperations.sc_muladd(sig.Slice(32, 32), hram, az, r); } }
/*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); * }*/ internal static void crypto_sign2(byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] sk, int skoffset) { byte[] az; byte[] r; byte[] hram; 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 GroupElementP3 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 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 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 hasher = new Sha512(); { hasher.Update(sk, skoffset, 32); az = hasher.Finish(); az[0] &= 248; az[31] &= 63; az[31] |= 64; 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 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) { Sha512 hasher = new Sha512(); { hasher.Update(sk, skoffset, 32); byte[] az = hasher.Finish(); ScalarOperations.ScClamp(az, 0); hasher.Init(); hasher.Update(az, 32, 32); hasher.Update(m, moffset, mlen); byte[] r = hasher.Finish(); ScalarOperations.ScReduce(r); GroupElementP3 R; GroupOperations.GeScalarmultBase(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); byte[] hram = hasher.Finish(); ScalarOperations.ScReduce(hram); byte[] s = new byte[32]; Array.Copy(sig, sigoffset + 32, s, 0, 32); ScalarOperations.ScMulAdd(s, hram, az, r); Array.Copy(s, 0, sig, sigoffset + 32, 32); CryptoBytes.Wipe(s); } }
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 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.Finish(); Assert.AreEqual(BitConverter.ToString(hashExpected), BitConverter.ToString(hash1)); hasher.Init(); hasher.Update(message, 0, message.Length); var hash2 = hasher.Finish(); Assert.AreEqual(BitConverter.ToString(hashExpected), BitConverter.ToString(hash2)); }