srp6a 0.1.0

Implementation of SRP 6a (Secure Remote Password) according to RFC 5054 (https://datatracker.ietf.org/doc/html/rfc5054)
Documentation
use num_bigint::BigUint;
use sha1::Sha1;

use crate::client::Client;
use crate::tests::test_utils::*;

#[test]
fn test_compute_k() {
    let client = Client::<Sha1>::new(create_test_group_1024());

    let expected_k = create_test_k();

    assert_eq!(client.k, expected_k);
}

#[test]
fn test_compute_verifier() {
    let client = Client::<Sha1>::new(create_test_group_1024());
    let salt = create_test_salt();

    let verifier = client.compute_verifier(TEST_USERNAME, TEST_PASSWORD, &salt);

    let expected_verifier = create_test_verifier();

    assert_eq!(verifier, expected_verifier);
}

#[test]
fn test_generate_keypair_from_private_key() {
    let client = Client::<Sha1>::new(create_test_group_1024());

    let (private_key, expected_public_key) = create_test_client_keypair();

    let (_, public_key) = client
        .generate_keypair_from_private_key(&private_key.to_bytes_be())
        .unwrap();

    assert_eq!(public_key, expected_public_key);
}

#[test]
fn test_generate_keypair() {
    let client = Client::<Sha1>::new(create_test_group_1024());

    let result = client.generate_keypair(128);
    assert!(result.is_ok());

    let (private, public) = result.unwrap();
    assert!(private > BigUint::from(0u32));
    assert!(public > BigUint::from(0u32));
    assert!(public < client.group.n);
}

#[test]
fn test_generate_keypair_invalid_length() {
    let client = Client::<Sha1>::new(create_test_group_1024());

    // Zero length
    let result = client.generate_keypair(0);
    assert!(matches!(
        result,
        Err(crate::client::ClientError::InvalidKeyLength(_))
    ));

    // Non-multiple of 8
    let result = client.generate_keypair(127);
    assert!(matches!(
        result,
        Err(crate::client::ClientError::InvalidKeyLength(_))
    ));

    // Length exceeds maximum
    let result = client.generate_keypair(2048);
    assert!(matches!(
        result,
        Err(crate::client::ClientError::InvalidKeyLength(_))
    ));
}

#[test]
fn test_compute_premaster_key() {
    let client = Client::<Sha1>::new(create_test_group_1024());
    let salt = create_test_salt();

    let (private_client_key, public_client_key) = create_test_client_keypair();

    let (_, public_server_key) = create_test_server_keypair();

    let premaster_key = client
        .compute_premaster_key(
            &public_server_key,
            &private_client_key,
            &public_client_key,
            &salt,
            TEST_USERNAME,
            TEST_PASSWORD,
        )
        .unwrap();

    let expected_premaster_key = create_test_premaster_key();

    assert_eq!(premaster_key, expected_premaster_key);
}