<commit_before>#!/usr/bin/env python

import unittest
import os.path
import os
import sys
import time
import thread

this_dir = os.path.dirname( os.path.abspath(__file__) )
    
build_dir = os.path.join( os.path.dirname(this_dir), 'build' )

if not os.path.exists( build_dir ):
    print 'Please run "python setup.py build" prior to running tests'
    sys.exit(1)
    
plat_dirs = [ d for d in os.listdir('build') if d.startswith('lib') ]

if not len(plat_dirs) == 1:
    print 'Unexpected build result... aborting'

plat_dir = os.path.join( build_dir, plat_dirs[0] )

sys.path.insert(0, os.path.join('build', plat_dir)  )



import srp
import srp._pysrp as _pysrp
import srp._ctsrp as _ctsrp

try:
    import srp._srp as _srp
except ImportError:
    print 'Failed to import srp._srp. Aborting tests'
    sys.exit(1)


test_g_hex = "2"
test_n_hex = '''\
AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4\
A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF60\
95179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF\
747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B907\
8717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB37861\
60279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DB\
FBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73'''


class SRPTests( unittest.TestCase ):

    def doit(self, u_mod, v_mod, g_mod, hash_alg=srp.SHA1, ng_type=srp.NG_2048, n_hex='', g_hex=''):
        User                           = u_mod.User
        Verifier                       = v_mod.Verifier
        create_salted_verification_key = g_mod.create_salted_verification_key

        username = 'testuser'
        password = '<PASSWORD>'

        _s, _v = create_salted_verification_key( username, password, hash_alg, ng_type, n_hex, g_hex )

        usr      = User( username, password, hash_alg, ng_type, n_hex, g_hex )
        uname, A = usr.start_authentication()
    
        # username, A => server
        svr      = Verifier( uname, _s, _v, A, hash_alg, ng_type, n_hex, g_hex )
        s,B      = svr.get_challenge()
        
        # s,B => client
        M        = usr.process_challenge( s, B )
        
        # M => server
        HAMK     = svr.verify_session( M )
    
        # HAMK => client
        usr.verify_session( HAMK )

        self.assertTrue( svr.authenticated() and usr.authenticated() )

    def test_pure_python_defaults(self):
        self.doit( _pysrp, _pysrp, _pysrp )

    def test_ctypes_defaults(self):
        self.doit( _ctsrp, _ctsrp, _ctsrp )

    def test_c_defaults(self):
        self.doit( _srp, _srp, _srp )

    def test_mix1(self):
        self.doit( _pysrp, _ctsrp, _srp )

    def test_mix2(self):
        self.doit( _pysrp, _srp, _ctsrp )

    def test_mix3(self):
        self.doit( _ctsrp, _pysrp, _srp )

    def test_mix4(self):
        self.doit( _ctsrp, _srp, _pysrp )

    def test_mix5(self):
        self.doit( _srp, _pysrp, _ctsrp )<commit_msg>Added more explicit tests of the values generated by the different implementations. Added test cases for the prime number size that we are using (NG_1024)<commit_after>#!/usr/bin/env python

import unittest
import os.path
import os
import sys
import time
import thread
import base64

this_dir = os.path.dirname( os.path.abspath(__file__) )
    
build_dir = os.path.join( os.path.dirname(this_dir), 'build' )

if not os.path.exists( build_dir ):
    print 'Please run "python setup.py build" prior to running tests'
    sys.exit(1)
    
plat_dirs = [ d for d in os.listdir('build') if d.startswith('lib') ]

if not len(plat_dirs) == 1:
    print 'Unexpected build result... aborting'

plat_dir = os.path.join( build_dir, plat_dirs[0] )

sys.path.insert(0, os.path.join('build', plat_dir)  )



import srp
import srp._pysrp as _pysrp
import srp._ctsrp as _ctsrp

try:
    import srp._srp as _srp
except ImportError:
    print 'Failed to import srp._srp. Aborting tests'
    sys.exit(1)


test_g_hex = "2"
test_n_hex = '''\
AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4\
A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF60\
95179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF\
747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B907\
8717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB37861\
60279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DB\
FBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73'''


class SRPTests( unittest.TestCase ):
    longMessage = True

    def get_hash_digest_length(self, hash_alg):
        hash_class = _pysrp._hash_map[hash_alg]
        h = hash_class()
        return len(h.hexdigest())

    def doit(self, u_mod, v_mod, g_mod, hash_alg=srp.SHA1, ng_type=srp.NG_2048, n_hex='', g_hex=''):
        User                           = u_mod.User
        Verifier                       = v_mod.Verifier
        create_salted_verification_key = g_mod.create_salted_verification_key

        username = 'testuser'
        password = '<PASSWORD>'

        _s, _v = create_salted_verification_key( username, password, hash_alg, ng_type, n_hex, g_hex )

        usr      = User( username, password, hash_alg, ng_type, n_hex, g_hex )
        uname, A = usr.start_authentication()
    
        # username, A => server
        svr      = Verifier( uname, _s, _v, A, hash_alg, ng_type, n_hex, g_hex )
        s,B      = svr.get_challenge()
        
        # s,B => client
        M        = usr.process_challenge( s, B )
        
        # M => server
        HAMK     = svr.verify_session( M )
    
        # HAMK => client
        usr.verify_session( HAMK )

        if ng_type == srp.NG_CUSTOM:
            key_length = len(n_hex)
        else:
            N, g = _pysrp._ng_const[ng_type]
            key_length = len(N)
        hash_digest_length = self.get_hash_digest_length(hash_alg)

        self.assertEqual(
            len(base64.b16encode(A)),
            key_length,
            "Incorrect length for client public ephemeral value %d != %d"
        )
        self.assertEqual(
            len(base64.b16encode(B)),
            key_length + hash_digest_length,
            "Incorrect length for server public ephemeral value"
        )
        self.assertEqual(
            len(base64.b16encode(_v)),
            key_length,
            "Incorrect length for verifier"
        )
        self.assertEqual(
            len(base64.b16encode(_s)),
            8,
            "Incorrect length for salt"
        )
        self.assertEqual(
            len(base64.b16encode(M)),
            hash_digest_length,
            "Incorrect length for session key verifier"
        )

        self.assertTrue( svr.authenticated() and usr.authenticated() )

    def test_pure_python_defaults(self):
        self.doit( _pysrp, _pysrp, _pysrp )

    def test_ctypes_defaults(self):
        self.doit( _ctsrp, _ctsrp, _ctsrp )

    def test_c_defaults(self):
        self.doit( _srp, _srp, _srp )

    def test_NG_1024(self):
        self.doit( _srp, _srp, _srp, ng_type=srp.NG_1024 )

    def test_pure_python_NG_1024(self):
        self.doit( _pysrp, _pysrp, _pysrp, ng_type=srp.NG_1024 )

    def test_mix1(self):
        self.doit( _pysrp, _ctsrp, _srp )

    def test_mix2(self):
        self.doit( _pysrp, _srp, _ctsrp )

    def test_mix3(self):
        self.doit( _ctsrp, _pysrp, _srp )

    def test_mix4(self):
        self.doit( _ctsrp, _srp, _pysrp )

    def test_mix5(self):
        self.doit( _srp, _pysrp, _ctsrp )
{'fraction_non_alphanumeric': 0.09237421383647798, 'fraction_numerical': 0.09630503144654089, 'mean_word_length': 2.8031888390632784, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7271484', 'n_tokens_mistral': 3426, 'n_tokens_neox': 2966, 'n_words': 548}