) // ECDH Shared secret clientPublicKey, _ := ecdh.X25519().NewPublicKey(clientPublicKeyBytes) // From KeyShare Extension sharedSecret, _ := ecdhServerPrivateKey.ECDH(clientPublicKey) // Generated in ServerHello // Early Secret zero32 := make([]byte, sha256.New().Size()) earlySecret := hkdf.Extract(sha256.New, zero32, zero32) secretState := DeriveSecret(earlySecret, "derived", [][]byte{}) // Handshake Secret handshakeSecret := hkdf.Extract(sha256.New, sharedSecret, secretState) secretState = DeriveSecret(handshakeSecret, "derived", [][]byte{}) // Handshake Traffic Secret for server serverHandshakeSecret := DeriveSecret(handshakeSecret, "s hs traffic", [][]byte{clientHello, serverHello}) // Key and IV for server serverWriteKey := HKDFExpandLabel(serverHandshakeSecret, "key", []byte{}, 16) serverWriteIV := HKDFExpandLabel(serverHandshakeSecret, "iv", []byte{}, 12) Generate clientHandshakeSecret similarly for later decryption Obtained from ClientHello (KeyShare Extension)