The server does not know the original values of the plaintext password so it stores the x calculation and the value of s are generated when the account is created. That's how it knows what s to send and that's how it knows how to generate M1 even though it doesn't know your password s = GetClient_s(Username); x = GetClient_x(UserName) these are stored in the db v = g^x mod N B = k * v + g^b mod N b = random k = H(N | g) A is sent from the client S = (A * v ^ u) mod N ^ b mod N K = interleave(S) u = H(A | B) so now, it can calc M1 M1 = M = H(H(N) xor H(g), H(I), s, A, B, K) and M2 M2 = H(A, M1, K) it sends its B, the client s from the db to the client the accountSalt is just a value used to identify the user it can actually be anything accountSalt = GetAccountID(username) SendToClient H(accountSalt), s, B, secondB Client: SendToServer A, M1, second_a server: sendtoclient M2, secondM2 client verify(M2), verify(secondM2) The second M2 is actually more like a second B or something its 128 bytes, Rob will post details tonight when the client creates an account, probably web based, generate a random value for s, store the s, and the email address in the database, then generate x which is H(s, H(I ":" p)) and store it in the db for the I value, I would use H(username), and that's what you would send for account salt. (Just the hash of the username) -so for the server x generation, x = H(s, H(Transform(H(username)) ":" p)) Then when you send 0x02 from the server, Send H(username), s, B, second, everything will work out perfectly. (just dont forget to transform the hash when calculating x) Lol, or you could be completely insecure and just save the plain text password and generate M1 exactly on the client. But, I say, generate x and store it, it's secure. -so, in your database, you will have username, s, x (again, x = H(s, H(Transform(H(username)) ":" p)) and s is random) - YOu get A from the client, and A is the only value you need from the client to generate M1 (and of course, the username, but that's sent in C->S 0x02) -Now, on the server, you generate M1, and then match it to the M1 that the client sent you (if they match, generate M2 and send it back to the client, but if your M1 doesn't match, then fail auth, but do not send M2 back.) If you send M2 back on a failed auth, they can likely brute M1 (BAD!)