1"""passlib.tests.test_handlers - tests for passlib hash algorithms"""
2#=============================================================================
3# imports
4#=============================================================================
5# core
6import logging; log = logging.getLogger(__name__)
7import warnings
8warnings.filterwarnings("ignore", ".*using builtin scrypt backend.*")
9# site
10# pkg
11from passlib import hash
12from passlib.tests.utils import HandlerCase, TEST_MODE
13from passlib.tests.test_handlers import UPASS_TABLE, PASS_TABLE_UTF8
14# module
15
16#=============================================================================
17# scrypt hash
18#=============================================================================
19class _scrypt_test(HandlerCase):
20    handler = hash.scrypt
21
22    known_correct_hashes = [
23        #
24        # excepted from test vectors from scrypt whitepaper
25        # (http://www.tarsnap.com/scrypt/scrypt.pdf, appendix b),
26        # and encoded using passlib's custom format
27        #
28
29        # salt=b""
30        ("", "$scrypt$ln=4,r=1,p=1$$d9ZXYjhleyA7GcpCwYoEl/FrSETjB0ro39/6P+3iFEI"),
31
32        # salt=b"NaCl"
33        ("password", "$scrypt$ln=10,r=8,p=16$TmFDbA$/bq+HJ00cgB4VucZDQHp/nxq18vII3gw53N2Y0s3MWI"),
34
35        #
36        # custom
37        #
38
39        # simple test
40        ("test", '$scrypt$ln=8,r=8,p=1$wlhLyXmP8b53bm1NKYVQqg$mTpvG8lzuuDk+DWz8HZIB6Vum6erDuUm0As5yU+VxWA'),
41
42        # different block value
43        ("password", '$scrypt$ln=8,r=2,p=1$dO6d0xoDoLT2PofQGoNQag$g/Wf2A0vhHhaJM+addK61QPBthSmYB6uVTtQzh8CM3o'),
44
45        # different rounds
46        (UPASS_TABLE, '$scrypt$ln=7,r=8,p=1$jjGmtDamdA4BQAjBeA9BSA$OiWRHhQtpDx7M/793x6UXK14AD512jg/qNm/hkWZG4M'),
47
48        # alt encoding
49        (PASS_TABLE_UTF8, '$scrypt$ln=7,r=8,p=1$jjGmtDamdA4BQAjBeA9BSA$OiWRHhQtpDx7M/793x6UXK14AD512jg/qNm/hkWZG4M'),
50
51        # diff block & parallel counts as well
52        ("nacl", '$scrypt$ln=1,r=4,p=2$yhnD+J+Tci4lZCwFgHCuVQ$fAsEWmxSHuC0cHKMwKVFPzrQukgvK09Sj+NueTSxKds')
53    ]
54
55    if TEST_MODE("full"):
56        # add some hashes with larger rounds value.
57        known_correct_hashes.extend([
58            #
59            # from scrypt whitepaper
60            #
61
62            # salt=b"SodiumChloride"
63            ("pleaseletmein", "$scrypt$ln=14,r=8,p=1$U29kaXVtQ2hsb3JpZGU"
64                              "$cCO9yzr9c0hGHAbNgf046/2o+7qQT44+qbVD9lRdofI"),
65
66            #
67            # openwall format (https://gitlab.com/jas/scrypt-unix-crypt/blob/master/unix-scrypt.txt)
68            #
69            ("pleaseletmein",
70             "$7$C6..../....SodiumChloride$kBGj9fHznVYFQMEn/qDCfrDevf9YDtcDdKvEqHJLV8D"),
71
72        ])
73
74    known_malformed_hashes = [
75        # missing 'p' value
76        '$scrypt$ln=10,r=1$wvif8/4fg1Cq9V7L2dv73w$bJcLia1lyfQ1X2x0xflehwVXPzWIUQWWdnlGwfVzBeQ',
77
78        # rounds too low
79        '$scrypt$ln=0,r=1,p=1$wvif8/4fg1Cq9V7L2dv73w$bJcLia1lyfQ1X2x0xflehwVXPzWIUQWWdnlGwfVzBeQ',
80
81        # invalid block size
82        '$scrypt$ln=10,r=A,p=1$wvif8/4fg1Cq9V7L2dv73w$bJcLia1lyfQ1X2x0xflehwVXPzWIUQWWdnlGwfVzBeQ',
83
84        # r*p too large
85        '$scrypt$ln=10,r=134217728,p=8$wvif8/4fg1Cq9V7L2dv73w$bJcLia1lyfQ1X2x0xflehwVXPzWIUQWWdnlGwfVzBeQ',
86    ]
87
88    def setUpWarnings(self):
89        super(_scrypt_test, self).setUpWarnings()
90        warnings.filterwarnings("ignore", ".*using builtin scrypt backend.*")
91
92    def populate_settings(self, kwds):
93        # builtin is still just way too slow.
94        if self.backend == "builtin":
95            kwds.setdefault("rounds", 6)
96        super(_scrypt_test, self).populate_settings(kwds)
97
98    class FuzzHashGenerator(HandlerCase.FuzzHashGenerator):
99
100        def random_rounds(self):
101            # decrease default rounds for fuzz testing to speed up volume.
102            return self.randintgauss(4, 10, 6, 1)
103
104# create test cases for specific backends
105scrypt_stdlib_test = _scrypt_test.create_backend_case("stdlib")
106scrypt_scrypt_test = _scrypt_test.create_backend_case("scrypt")
107scrypt_builtin_test = _scrypt_test.create_backend_case("builtin")
108
109#=============================================================================
110# eof
111#=============================================================================
112