package protocol import ( "crypto/sha1" "crypto/sha512" "math/big" ) // Curve25519 Prime: 2^255 - 19 var P *big.Int func init() { P, _ = new(big.Int).SetString("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed", 16) } // Ed25519 Y (Compressed) to Curve25519 (Montgomery) U // u = (1 + y) / (1 - y) func EdwardsToMontgomery(yBytes []byte) ([]byte, error) { // 1. Decode y (little endian, clamped?) // "The 32-byte public key is the 32-byte little-endian encoding of the Point." // High bit is sign of x (ignored for U-coord conv usually?). // Reverse bytes to big.Int y := new(big.Int).SetBytes(Reverse(yBytes)) // Clear high bit? // Ed25519 compressed form: high bit of last byte is X sign. // y &= ~(1 << 255) bit255 := big.NewInt(1) bit255.Lsh(bit255, 255) if y.Cmp(bit255) >= 0 { y.Sub(y, bit255) } one := big.NewInt(1) // num = 1 + y num := new(big.Int).Add(one, y) num.Mod(num, P) // den = 1 - y den := new(big.Int).Sub(one, y) // Handle negative result for modular arithmetic if den.Sign() < 0 { den.Add(den, P) } den.Mod(den, P) // denInv denInv := new(big.Int).ModInverse(den, P) // u = num * denInv u := new(big.Int).Mul(num, denInv) u.Mod(u, P) // Encode u (32 bytes little endian) uBytes := u.Bytes() uBytesRev := Reverse(uBytes) // Pad to 32 res := make([]byte, 32) copy(res, uBytesRev) // Copy into start (little endian usually means LSB at 0?) // Wait. BigInt Bytes() returns Big Endian. // Reverse(BigEndian) -> Little Endian. // If uBytes is shorter than 32, we need to pad ZEROS at the END (high bytes) in Little Endian. // e.g. Value 1. BigEndian: [1]. Reverse: [1]. // Result [1, 0, 0, ...] return res, nil } func Reverse(b []byte) []byte { l := len(b) r := make([]byte, l) for i := 0; i < l; i++ { r[i] = b[l-1-i] } return r } // CalculateSharedSecret inputs: // serverPubKey (Montgomery U, 32 bytes) // clientPrivKey (Scalar, 32 bytes) func CalculateSharedSecret(serverPub, clientPriv []byte) []byte { // Use x/crypto/curve25519 // ScalarMult(dst, scalar, point) // Placeholder as logic is in handshake.go currently return nil } // Helper to expand hashes func Sha1Array(data []byte) [20]byte { return sha1.Sum(data) } func Sha512Array(data []byte) [64]byte { return sha512.Sum512(data) }