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 KeyExchange(ArraySegment <byte> sharedKey, ArraySegment <byte> publicKey, ArraySegment <byte> privateKey) { if (sharedKey.Array == null) { throw new ArgumentNullException(nameof(sharedKey)); } if (publicKey.Array == null) { throw new ArgumentNullException(nameof(sharedKey)); } 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 var edwardsY, publicKey.Array, publicKey.Offset); FieldOperations.fe_1(out var edwardsZ); MontgomeryCurve25519.EdwardsToMontgomeryX(out var montgomeryX, ref edwardsY, ref edwardsZ); var h = Sha512.Hash(privateKey.Array, privateKey.Offset, 32); ScalarOperations.ScClamp(h, 0); MontgomeryOperations.ScalarMult(out var sharedMontgomeryX, h, 0, ref montgomeryX); CryptoBytes.Wipe(h); FieldOperations.fe_tobytes(sharedKey.Array, sharedKey.Offset, ref sharedMontgomeryX); MontgomeryCurve25519.KeyExchangeOutputHashNaCl(sharedKey.Array, sharedKey.Offset); }
// 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); }