internal static void EdwardsToMontgomeryX(out FieldElement montgomeryX, ref FieldElement edwardsY, ref FieldElement edwardsZ) { FieldOperations.fe_add(out var tempX, ref edwardsZ, ref edwardsY); FieldOperations.fe_sub(out var tempZ, ref edwardsZ, ref edwardsY); FieldOperations.fe_invert(out tempZ, ref tempZ); FieldOperations.fe_mul(out montgomeryX, ref tempX, ref tempZ); }
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); }