I have been wracking my brain trying to develop a functioning implementation of SRP-6a in Python to use with a 3rd-party API that claims to use SRP-6a with $N=$ 2048-bit prime and generator of $2$. Unfortunately it has proven quite difficult to find two implementations that "match" to themselves.

For example, Stanford’s “SRP Protocol Design” page indicates that $K=H(S)$ (and I'm assuming that $H$ is SHA1 even though some implementations are using SHA256), but RFC2945 (original RFC for SRP) indicates $K$ is an Interleave-SHA1. So which is it?

Second, the proof that the user generates ($M$) is stated, "one possible way" is $M=H(H(N) \oplus H(g), H(I), s, A, B, K)$ whereas some implementations have $M=H(A,B,S)$? Which is it?

Finally, if I look at the original RFC2945 I see pretty much what is written in SRP Protocol Design, with the exception that $k=H(N,g)$ in 6a and for example in the design URL $B=(kv + g^b) % N$ (I guess, its never clear where to apply modulo $N$ if its just left out and written as "All arithmetic is done modulo N) where as in RFC2945 B is simply $(v+g^b) % N$.

Finally, are there test vectors other than $N$=1024-bit, $g=2$ , I can recreate the vector that exists even though nothing every shows the expected calculation for $K$ or $M$.

Apologies for first post to this site as sounding needy, but I've been trying to wrap my mind around this and work with a blackbox application that I simply fail the proof every time even after checking and doublechecking my code. :-(

  • 1
    $\begingroup$ Normally, $H$, $N$, and $g$ are the parameters that need to be agreed-upon by communicating parties as they're not part of the SRP spec. For example, RFC 5054 uses SHA-1 and I've seen other implementations use SHA-256. Also note that RFC2945 describes SRP-3, thus some differences with SRP-6a. If your blackbox is a conforming SRP-6a then I'd expect $M$ is computed per-spec, i.e. $M=H(H(N) \oplus H(g), H(I) ,s, A, B, K)$. But the only way to be 100% sure is to reverse engineer the blackbox. $\endgroup$
    – Andrey
    Aug 8, 2014 at 7:28
  • $\begingroup$ That's interesting, because srp.stanford.edu/srp6.ps says M1 (client) is H(A, B, S). I would consider it unrealistic to reverse-engineer the 3rd-party box; the documentation simply says "conforms to SRP-6a." So, it sounds like the upshot is, there is no formal definition of SRP-6a to conform to. Now you see the frustration, multiple specifications, multiple formulae for a given parameter. I'll keep chipping away I suppose. $\endgroup$
    – Joe
    Aug 8, 2014 at 12:42
  • $\begingroup$ Good catch with $H(A, B, S)$! I haven't seen this in RFCs or on their main website... If there's a binary to reverse engineer I'd be happy to take a look. Otherwise, IMO, "Conforms to SRP-6a" is nowhere near sufficient to produce matching implementation. You need (at least) $H$, $N$, and $g$. $\endgroup$
    – Andrey
    Aug 8, 2014 at 13:07
  • $\begingroup$ Oh, if I could provide the binary I'd be delighted to work with you, unfortunately it was delivered under an NDA and requires a significant amount of "scaffolding" to even get to the SRP step. That's where a separate reference implementation that calculated all of the parameters would be helpful! $\endgroup$
    – Joe
    Aug 8, 2014 at 14:29
  • 2
    $\begingroup$ @Andrey Slow hashes have the same purpose as with any other protocol - to protect the passwords if the database containing the hashes leaks. $\endgroup$ Aug 8, 2014 at 18:41

1 Answer 1


SRP protocol is quite abstract so to provide matching implementation for version 6a you need to know following:

  • N, g - group parameters
  • H - hash function, there can be different hash functions used for different values
  • how is private key x calculated
  • how is shared session key K calculated
  • how are evidence messages (M1, M2) calculated

In addition you need to know what is internal representation of numbers (byte order, padding) and what is the format of messages being exchanged between client and server.

Without that knowledge all you can do is reverse enginner (even without disassembling binary ie. you could deduce what might be hash function based on size of M1) or try your luck with different configurations. For example (based on RFC 5054 and SRP-6a summary):

  • byte order: big endian
  • encoding: UTF-8 (for username and password)
  • N = 2048 bit prime from appendix A
  • g = 2
  • H = SHA1
  • x = H(s | H(I | ':' | P))
  • k = H(N | PAD(g))
  • u = H(PAD(N) | PAD(B))
  • K = H(S)
  • M1 = H(H(N) xor H(g), H(I), s, A, B, K)
  • M2 = H(A, M1, K)

As for the test vectors I haven't found others then those at RFC 5054 and on Stanford SRP demo page.

  • $\begingroup$ Another key implementation detail is how the hash values which are binary are converted into big integers. One of the RFCs suggests a conversion routine which is language independent. Another approach is to use the hex representation of the byte array as a hexidecimal number representation as the math library of the language you are using will then do the conversion. The challenge with that is that the math library will trim leading zeros in the interpretation of the hex number. All of which are details which make for painful debugging when implementing SRP across different languages. $\endgroup$
    – simbo1905
    Jan 22, 2016 at 8:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.