Skip to main content

srp6

CI pypi downloads versions license

A pure Python implementation of the Secure Remote Password protocol (SRP version 6a) with GSA mode support.

Overview

SRP (Secure Remote Password) is a password-authenticated key exchange protocol that allows secure authentication without transmitting the password over the network. This implementation follows RFC 5054 and includes support for GSA (Grand Slam Authentication) mode.

Features

  • Pure Python - No external dependencies, uses only Python standard library
  • Multiple Key Sizes - Support for 1024 to 8192-bit primes from RFC 5054
  • GSA Mode - Compatible with GSA authentication services
  • Hash Cash - Includes proof-of-work implementation for rate limiting
  • Type Hints - Full type annotation support

Installation

pip install srp6

Usage

Basic SRP Client

from srp6 import SRPClient, pbkdf2_sha256

# Create client with username
client = SRPClient(b"user@example.com")

# Derive password using PBKDF2 (typically from server's salt)
password = b"secret_password"
salt = b"server_provided_salt"
derived_password = pbkdf2_sha256(password, salt, iterations=10000)
client.password = derived_password

# Get public ephemeral to send to server
A = client.get_public_ephemeral()

# After receiving server's salt and public ephemeral B:
# Generate client proof M1
M1 = client.generate(salt=server_salt, server_public=server_B)

# Get session key for encrypted communication
session_key = client.session_key

Using Different Prime Groups

from srp6 import SRPClient, SRP_1024, SRP_4096

# Use 1024-bit prime (faster, less secure)
client_1024 = SRPClient(b"user", group=1024)

# Use 4096-bit prime (slower, more secure)
client_4096 = SRPClient(b"user", group=4096)

# Or pass the group directly
client = SRPClient(b"user", group=SRP_4096)

Hash Cash (Proof of Work)

from srp6 import generate_hashcash, verify_hashcash

# Generate proof of work
bits = 11  # Difficulty level (number of leading zero bits)
challenge = "server_challenge_string"
hashcash = generate_hashcash(bits, challenge)

# Verify proof of work
is_valid = verify_hashcash(hashcash, bits)

API Reference

SRPClient

class SRPClient:
    def __init__(
        self,
        username: bytes,
        a: int | None = None,
        group: SRPGroup | int | None = None
    ):
        """
        Initialize SRP client.

        Args:
            username: The username/identity bytes
            a: Optional private ephemeral value (for testing)
            group: SRP group - SRPGroup instance, bit size (1024/2048/4096), or None for default (2048)
        """

Properties:

  • password - Set the derived password (from PBKDF2)
  • session_key - Get the computed session key K
  • M - Get the client proof M1
  • group - Get the SRP group being used

Methods:

  • get_public_ephemeral() - Get client's public ephemeral A
  • generate(salt, server_public) - Generate client proof M1
  • generate_m2() - Generate M2 for verification

Prime Groups

All groups from RFC 5054 (1024 to 8192 bits):

  • SRP_1024 - 1024 bits (128 bytes) - Legacy, not recommended
  • SRP_1536 - 1536 bits (192 bytes) - Legacy
  • SRP_2048 - 2048 bits (256 bytes) - Standard (default)
  • SRP_3072 - 3072 bits (384 bytes) - Enhanced security
  • SRP_4096 - 4096 bits (512 bytes) - High security
  • SRP_6144 - 6144 bits (768 bytes) - Very high security
  • SRP_8192 - 8192 bits (1024 bytes) - Maximum security

Utility Functions

# Hashing
hash_sha256(data: bytes) -> bytes
pbkdf2_sha256(password: bytes, salt: bytes, iterations: int, dklen: int = 32) -> bytes

# Byte conversions
bytes_to_int(b: bytes) -> int
int_to_bytes(n: int, length: int | None = None) -> bytes
to_hex(data: bytes) -> str
from_hex(hex_str: str) -> bytes

GSA Mode

This implementation supports GSA (Grand Slam Authentication) mode, which differs from standard SRP-6a in the following ways:

  1. Identity not included in x computation - The password verifier x is computed as H(salt || H(":" || password)) instead of H(salt || H(I || ":" || password))

  2. Generator padding - The generator g is padded to N_BYTES when computing H(g) for the M1 proof

  3. No padding for A, B, S - The public ephemerals A and B, and the shared secret S are NOT padded in their respective computations

Protocol Details

Notation

  • N - Large safe prime (N = 2q+1, where q is prime)
  • g - Generator modulo N
  • k - Multiplier parameter: k = H(N || pad(g))
  • s - User's salt
  • I - Username
  • p - Cleartext password
  • H() - One-way hash function (SHA-256)
  • x - Private key derived from password and salt
  • v - Password verifier stored on server
  • a, b - Secret ephemeral values
  • A, B - Public ephemeral values
  • S - Premaster secret
  • K - Session key
  • M1, M2 - Proofs

Registration (One-Time Setup)

x = H(s || H(I || ":" || p))     # Private key
v = g^x % N                       # Verifier (stored on server)

The server stores: (I, s, v). The password p is never stored.

Authentication Handshake

Client                                  Server
------                                  ------
  |                                       |
  |  -------- I, A = g^a % N ------>      |
  |                                       |
  |  <------- s, B = kv + g^b % N --      |
  |                                       |
  |  u = H(pad(A) || pad(B))              |  u = H(pad(A) || pad(B))
  |  x = H(s || H(I || ":" || p))         |
  |  S = (B - kg^x)^(a + ux) % N          |  S = (Av^u)^b % N
  |  K = H(S)                             |  K = H(S)
  |                                       |
  |  -------- M1 = H(...) ---------->     |  (verify M1)
  |                                       |
  |  (verify M2) <------ M2 = H(...) --   |
  |                                       |
  |  [Session key K established]          |

Client Calculations

  1. Generate random a, compute A = g^a % N
  2. Receive s, B from server
  3. Compute u = H(pad(A) || pad(B))
  4. Compute k = H(N || pad(g))
  5. Derive x = H(s || H(I || ":" || p))
  6. Compute S = (B - k * g^x)^(a + u*x) % N
  7. Compute session key K = H(S)
  8. Compute proof M1 = H(H(N) XOR H(g) || H(I) || s || A || B || K)

Server Calculations

  1. Look up s, v for user I
  2. Generate random b, compute B = k*v + g^b % N
  3. Receive A from client
  4. Compute u = H(pad(A) || pad(B))
  5. Compute S = (A * v^u)^b % N
  6. Compute session key K = H(S)
  7. Verify client proof M1
  8. Compute server proof M2 = H(A || M1 || K)

Security Safeguards

The protocol aborts if any of these conditions occur:

  • Client aborts if B % N == 0 (malicious server)
  • Client aborts if u == 0 (compromised exchange)
  • Server aborts if A % N == 0 (malicious client)
  • Server aborts if client proof M1 is invalid

Protocol Flow Diagram

Client                                  Server
------                                  ------
  |                                       |
  |  -------- username, A -------->       |
  |                                       |
  |  <------- salt, B -------------       |
  |                                       |
  |  -------- M1 (proof) --------->       |
  |                                       |
  |  <------- M2 (verification) ---       |
  |                                       |
  |  [Session key K established]          |

Examples

See the examples directory for complete working examples:

Run examples:

python examples/01_signup.py
python examples/02_authentication.py

References

License

MIT License - see LICENSE for details.

Release files for srp6 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for srp6 0.1.1
File Size Uploaded
srp6-0.1.1.tar.gz 12.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for srp6 0.1.1
File Interpreter ABI Platform
srp6-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 25.1 kB

Release files / srp6-0.1.1.tar.gz

Download URL srp6-0.1.1.tar.gz
Size 12.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9deca3d8d1592c65a442cc491e0fbf9f75280877cbcca4f74d7ca12129e5241c
BLAKE2b-256 checksum
How to use checksums
f81bc001742d1bf99834e59e1367a62c4c03139c4291ac751b3632fd166521c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 18, 2026.

Transparency log

Release files / srp6-0.1.1-py3-none-any.whl

Download URL srp6-0.1.1-py3-none-any.whl
Size 13.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0acb5a909168c8cf2d572e7786427a292193de392cbe771a3b0cb66d9021bf08
BLAKE2b-256 checksum
How to use checksums
519167c0d3b0e4b3e0b5cc196a31f9f0e8c6c3844e855ffe0792866564505db6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page