public static bool crypto_sign_verify(ReadOnlySpan <byte> sig, ReadOnlySpan <byte> m, ReadOnlySpan <byte> pk) { if ((sig[63] & 224) != 0) { return(false); } if (GroupOperations.ge_frombytes_negate_vartime(out var A, pk) != 0) { return(false); } var hasher = new Sha512(); hasher.Update(sig.Slice(0, 32)); hasher.Update(pk.Slice(0, 32)); hasher.Update(m); Span <byte> h = stackalloc byte[64]; hasher.Finish(h); ScalarOperations.sc_reduce(h); GroupOperations.ge_double_scalarmult_vartime(out var R, h, in A, sig.Slice(32, 32)); Span <byte> checkr = stackalloc byte[32]; GroupOperations.ge_tobytes(checkr, in R); var result = CryptoBytes.ConstantTimeEquals(checkr, sig, 32); CryptoBytes.Wipe(h); CryptoBytes.Wipe(checkr); return(result); }
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 void Wipe() { var bytes = (byte[])_bytes.Clone(); CryptoBytes.Wipe(bytes); Assert.IsTrue(bytes.All(b => b == 0)); }
public void Wipe() { var bytes = (byte[])_bytes.Clone(); CryptoBytes.Wipe(bytes); bytes.All(b => b == 0).Should().BeTrue(); }
/*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 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 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_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 WipeSegment() { var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var wipedBytes = new byte[] { 1, 2, 0, 0, 0, 0, 0, 8, 9, 10 }; CryptoBytes.Wipe(new ArraySegment <byte>(bytes, 2, 5)); TestHelpers.AssertEqualBytes(wipedBytes, bytes); }
public static byte[] ExpandedPrivateKeyFromSeed(byte[] privateKeySeed) { byte[] privateKey; byte[] publicKey; KeyPairFromSeed(out publicKey, out privateKey, privateKeySeed); CryptoBytes.Wipe(publicKey); return(privateKey); }
public void WipeInterval() { var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var wipedBytes = new byte[] { 1, 2, 0, 0, 0, 0, 0, 8, 9, 10 }; CryptoBytes.Wipe(bytes, 2, 5); TestHelpers.AssertEqualBytes(wipedBytes, bytes); }
/// <summary> /// Signs the transaction. /// </summary> /// <param name="keyPair">The key pair.</param> /// <param name="payload">The payload.</param> /// <returns>The signature.</returns> internal static byte[] SignTransaction(KeyPair keyPair, byte[] payload) { var sig = new byte[64]; var sk = new byte[64]; Array.Copy(keyPair.PrivateKey, sk, 32); Array.Copy(keyPair.PublicKey, 0, sk, 32, 32); Ed25519.crypto_sign2(sig, payload, sk, 32); CryptoBytes.Wipe(sk); return(sig); }
// 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); }
/// <summary> /// Signs the specified data with this keypair. /// </summary> /// <param name="data">The data.</param> /// <returns>System.Byte[].</returns> /// <exception cref="ArgumentNullException">data</exception> public byte[] Sign(byte[] data) { if (data == null) { throw new ArgumentNullException(nameof(data)); } var sig = new byte[64]; var sk = new byte[64]; Array.Copy(PrivateKey, sk, 32); Array.Copy(PublicKey, 0, sk, 32, 32); Ed25519.crypto_sign2(sig, data, sk, 32); CryptoBytes.Wipe(sk); return(sig); }
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); 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 static void CryptoSignKeypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset) { int i; Array.Copy(seed, seedoffset, sk, skoffset, 32); var h = Sha512.Hash(sk, skoffset, 32); //ToDo: Remove alloc ScalarOperations.ScClamp(h, 0); stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.GeScalarmultBase(out var a, h, 0); stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.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 static void CryptoSignKeyPair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset) { int i; Array.Copy(seed, seedoffset, sk, skoffset, 32); var h = Sha512.Hash(sk, skoffset, 32); ScalarOperations.Clamp(h, 0); GroupOperations.ScalarMultBase(out var A, h, 0); GroupOperations.P3ToBytes(pk, pkoffset, ref A); for (i = 0; i < 32; ++i) { sk[skoffset + 32 + i] = pk[pkoffset + i]; } CryptoBytes.Wipe(h); }
/*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 void CryptoSignKeypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset) { int i; Array.Copy(seed, seedoffset, sk, skoffset, 32); byte[] h = Sha512.Hash(sk, skoffset, 32); //ToDo: Remove alloc ScalarOperations.ScClamp(h, 0); GroupOperations.GeScalarmultBase(out GroupElementP3 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); }
/// <summary> /// Initializes a new instance of the <see cref="Signature"/> class. /// </summary> /// <remarks> /// Uses twisted edwards elliptic curve, Ed25519, to produce signatures. /// </remarks> /// <param name="data">The data bytes to sign.</param> /// <param name="privateKey">The private key used to sign the bytes.</param> /// <example> /// This sample shows how to create a new instance of the <see cref="Signature"/> class and produce a signature. /// <code> /// class TestClass /// { /// static void Main() /// { /// byte[] bytes = new byte[10]; /// /// Signature sig = new Signature(bytes, new PrivateKey("0705c2634de7e58325dabc58c4a794559be4d55d102d3aafcb189acb2e596add")); /// /// string signature = sig._Signature; /// } /// } /// </code> /// </example> public Signature(byte[] data, PrivateKey privateKey) { var sig = new byte[64]; try { var sk = new byte[64]; Array.Copy(CryptoBytes.FromHexString(StringUtils.ConvertToUnsecureString(privateKey.Raw)), sk, 32); Array.Copy( CryptoBytes.FromHexString( new PublicKey(PublicKeyConversion.ToPublicKey(privateKey)).Raw), 0, sk, 32, 32); Ed25519.crypto_sign2(sig, data, sk, 32); CryptoBytes.Wipe(sk); } finally { _Signature = sig; } }
public static void crypto_sign2( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] sk, int skoffset) { byte[] az = new byte[64]; byte[] r = new byte[64]; byte[] hram = new byte[64]; GroupElementP3 R; var hasher2 = new Sha3Digest(512); { hasher2.BlockUpdate(sk, 0, 32); hasher2.DoFinal(az, 0); ScalarOperations.sc_clamp(az, 0); hasher2.Reset(); hasher2.BlockUpdate(az, 32, 32); hasher2.BlockUpdate(m, moffset, mlen); hasher2.DoFinal(r, 0); ScalarOperations.sc_reduce(r); GroupOperations.ge_scalarmult_base(out R, r, 0); GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R); hasher2.Reset(); hasher2.BlockUpdate(sig, sigoffset, 32); hasher2.BlockUpdate(sk, skoffset + 32, 32); hasher2.BlockUpdate(m, moffset, mlen); hasher2.DoFinal(hram, 0); ScalarOperations.sc_reduce(hram); var s = new byte[32]; 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); } }
// 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[] 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 hash = new KeccakDigest(512); hash.BlockUpdate(sig, sigoffset, 32); hash.BlockUpdate(pk, pkoffset, 32); hash.BlockUpdate(m, moffset, mlen); var b = new byte[64]; hash.DoFinal(b, 0); ScalarOperations.sc_reduce(b); var sm32 = new byte[32];//todo: remove allocation Array.Copy(sig, sigoffset + 32, sm32, 0, 32); GroupOperations.ge_double_scalarmult_vartime(out R, b, ref A, sm32); GroupOperations.ge_tobytes(checkr, 0, ref R); var result = CryptoBytes.ConstantTimeEquals(checkr, 0, sig, sigoffset, 32); CryptoBytes.Wipe(b); CryptoBytes.Wipe(checkr); return(result); }
internal 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 digest = new Sha3Digest(512); //new // tried and failed -> new Sha3Digest(512); byte[] h = new byte[64]; // byte[] ha = Sha512.Hash(sk, skoffset, 32);//ToDo: Remove alloc digest.BlockUpdate(sk, skoffset, 32); // new digest.DoFinal(h, 0); // new 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 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 = Blake2Fast.Blake2b.CreateIncrementalHasher(64); //var hasher = new Sha512(); { hasher.Update(new ArraySegment <byte>(sk, skoffset, 32)); az = hasher.Finish(); ScalarOperations.sc_clamp(az, 0); hasher = Blake2Fast.Blake2b.CreateIncrementalHasher(64); hasher.Update(new ArraySegment <byte>(az, 32, 32)); hasher.Update(new ArraySegment <byte>(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 = Blake2Fast.Blake2b.CreateIncrementalHasher(64); hasher.Update(new ArraySegment <byte>(sig, sigoffset, 32)); hasher.Update(new ArraySegment <byte>(sk, skoffset + 32, 32)); hasher.Update(new ArraySegment <byte>(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 crypto_sign_verify( byte[] signature, int signatureOffset, byte[] message, int messageOffset, int messageLength, byte[] publicKey, int publicKeyOffset) { byte[] h; byte[] checkr = new byte[32]; GroupElementP3 A; GroupElementP2 R; if ((signature[signatureOffset + 63] & 224) != 0) { return(false); } if (GroupOperations.ge_frombytes_negate_vartime(out A, publicKey, publicKeyOffset) != 0) { return(false); } var hasher = new Sha512(); hasher.Update(signature, signatureOffset, 32); hasher.Update(publicKey, publicKeyOffset, 32); hasher.Update(message, messageOffset, messageLength); h = hasher.FinalizeHash(); ScalarOperations.sc_reduce(h); var sm32 = new byte[32];//todo: remove allocation Array.Copy(signature, signatureOffset + 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, signature, signatureOffset, 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); }
// 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 CryptoSignVerify( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] pk, int pkoffset) { var checkr = new byte[32]; GroupElementP3 A; GroupElementP2 R; if ((sig[sigoffset + 63] & 224) != 0) { return(false); } if (stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.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); var h = hasher.Finish(); ScalarOperations.ScReduce(h); var sm32 = new byte[32]; //todo: remove allocation Array.Copy(sig, sigoffset + 32, sm32, 0, 32); stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32); stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.GeToBytes(checkr, 0, ref R); var result = CryptoBytes.ConstantTimeEquals(checkr, 0, sig, sigoffset, 32); CryptoBytes.Wipe(h); CryptoBytes.Wipe(checkr); return(result); }
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 hasher = Blake2Fast.Blake2b.CreateIncrementalHasher(64); hasher.Update(new ArraySegment <byte>(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); }
//[Obsolete("Needs more testing")] 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"); } FieldOperations.fe_frombytes(out FieldElement edwardsY, publicKey.Array, publicKey.Offset); FieldOperations.fe_1(out FieldElement edwardsZ); MontgomeryCurve25519.EdwardsToMontgomeryX(out FieldElement montgomeryX, ref edwardsY, ref edwardsZ); byte[] h = Sha512.Hash(privateKey.Array, privateKey.Offset, 32);//ToDo: Remove alloc ScalarOperations.sc_clamp(h, 0); MontgomeryOperations.scalarmult(out FieldElement sharedMontgomeryX, h, 0, ref montgomeryX); CryptoBytes.Wipe(h); FieldOperations.fe_tobytes(sharedKey.Array, sharedKey.Offset, ref sharedMontgomeryX); MontgomeryCurve25519.KeyExchangeOutputHashNaCl(sharedKey.Array, sharedKey.Offset); }
/*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); } }