Last time I looked, which was admittedly a while ago - they used K (40 byte result of SRP6), seeded a HMAC-SHA1() with the values below into two seperate hashes and initialized two ARC4 contexts (one for sending, one for receiving - each way having it's own seed). They would then force through 1024 bytes through the context to roll the key by 1024.
Here's the code I used - credit to wcell I believe
Code:
/// <summary>
/// This is the key the client uses to encrypt its packets
/// This is also the key the server uses to decrypt the packets
/// </summary>
private static readonly byte[] ServerDecryptionKey =
{
0xF4, 0x66, 0x31, 0x59, 0xFC, 0x83, 0x6E, 0x31,
0x31, 0x02, 0x51, 0xD5, 0x44, 0x31, 0x67, 0x98
};
/// <summary>
/// This is the key the client uses to decrypt server packets
/// This is also the key the server uses to encrypt the packets
/// </summary>
private static readonly byte[] ServerEncryptionKey =
{
0x22, 0xBE, 0xE5, 0xCF, 0xBB, 0x07, 0x64, 0xD9,
0x00, 0x45, 0x1B, 0xD0, 0x24, 0xB8, 0xD5, 0x45
};
// This is valid as HMAC-SHA1 transforms can be reused
static readonly HMACSHA1 s_decryptClientDataHMAC = new HMACSHA1(ServerDecryptionKey);
static readonly HMACSHA1 s_encryptServerDataHMAC = new HMACSHA1(ServerEncryptionKey);
/// <summary>
/// Decrypts data from Server
/// </summary>
private readonly ARC4 InData;
/// <summary>
/// Encrypts data for server
/// </summary>
private readonly ARC4 OutData;
public PacketCrypt(byte[] sessionKey)
{
byte[] encryptHash = s_encryptServerDataHMAC.ComputeHash(sessionKey);
byte[] decryptHash = s_decryptClientDataHMAC.ComputeHash(sessionKey);
// Used by the client to decrypt packets sent by the server
InData = new ARC4(encryptHash); // CLIENT-SIDE
// Used by the server to decrypt packets sent by the client
var decryptClientData = new ARC4(decryptHash); // SERVER-SIDE
// Used by the server to encrypt packets sent to the client
var encryptServerData = new ARC4(encryptHash); // SERVER-SIDE
// Used by the client to encrypt packets sent to the server
OutData = new ARC4(decryptHash); // CLIENT-SIDE
// Use the 2 encryption objects to generate a common starting point
var syncBuffer = new byte[1024];
encryptServerData.Process(syncBuffer, 0, syncBuffer.Length);
InData.Process(syncBuffer, 0, syncBuffer.Length);
// Use the 2 decryption objects to generate a common starting point
syncBuffer = new byte[1024];
OutData.Process(syncBuffer, 0, syncBuffer.Length);
decryptClientData.Process(syncBuffer, 0, syncBuffer.Length);
}