aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/nacl/pwhash/argon2id.py
blob: 1b86d69e141b453a1bafd50197103923ff400d69 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# Copyright 2013 Donald Stufft and individual contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import nacl.bindings
import nacl.encoding

from . import _argon2

ALG = _argon2.ALG_ARGON2ID13
STRPREFIX = nacl.bindings.crypto_pwhash_argon2id_STRPREFIX

SALTBYTES = _argon2.SALTBYTES

PASSWD_MIN = _argon2.PASSWD_MIN
PASSWD_MAX = _argon2.PASSWD_MAX

PWHASH_SIZE = _argon2.PWHASH_SIZE

BYTES_MIN = _argon2.BYTES_MIN
BYTES_MAX = _argon2.BYTES_MAX

verify = _argon2.verify

MEMLIMIT_MIN = nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_MIN
MEMLIMIT_MAX = nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_MAX
OPSLIMIT_MIN = nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_MIN
OPSLIMIT_MAX = nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_MAX

OPSLIMIT_INTERACTIVE = (
    nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE
)
MEMLIMIT_INTERACTIVE = (
    nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE
)
OPSLIMIT_SENSITIVE = nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE
MEMLIMIT_SENSITIVE = nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE

OPSLIMIT_MODERATE = nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_MODERATE
MEMLIMIT_MODERATE = nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_MODERATE


def kdf(
    size: int,
    password: bytes,
    salt: bytes,
    opslimit: int = OPSLIMIT_SENSITIVE,
    memlimit: int = MEMLIMIT_SENSITIVE,
    encoder: nacl.encoding.Encoder = nacl.encoding.RawEncoder,
) -> bytes:
    """
    Derive a ``size`` bytes long key from a caller-supplied
    ``password`` and ``salt`` pair using the argon2i
    memory-hard construct.

    the enclosing module provides the constants

        - :py:const:`.OPSLIMIT_INTERACTIVE`
        - :py:const:`.MEMLIMIT_INTERACTIVE`
        - :py:const:`.OPSLIMIT_MODERATE`
        - :py:const:`.MEMLIMIT_MODERATE`
        - :py:const:`.OPSLIMIT_SENSITIVE`
        - :py:const:`.MEMLIMIT_SENSITIVE`

    as a guidance for correct settings.

    :param size: derived key size, must be between
                 :py:const:`.BYTES_MIN` and
                 :py:const:`.BYTES_MAX`
    :type size: int
    :param password: password used to seed the key derivation procedure;
                     it length must be between
                     :py:const:`.PASSWD_MIN` and
                     :py:const:`.PASSWD_MAX`
    :type password: bytes
    :param salt: **RANDOM** salt used in the key derivation procedure;
                 its length must be exactly :py:const:`.SALTBYTES`
    :type salt: bytes
    :param opslimit: the time component (operation count)
                     of the key derivation procedure's computational cost;
                     it must be between
                     :py:const:`.OPSLIMIT_MIN` and
                     :py:const:`.OPSLIMIT_MAX`
    :type opslimit: int
    :param memlimit: the memory occupation component
                     of the key derivation procedure's computational cost;
                     it must be between
                     :py:const:`.MEMLIMIT_MIN` and
                     :py:const:`.MEMLIMIT_MAX`
    :type memlimit: int
    :rtype: bytes

    .. versionadded:: 1.2
    """

    return encoder.encode(
        nacl.bindings.crypto_pwhash_alg(
            size, password, salt, opslimit, memlimit, ALG
        )
    )


def str(
    password: bytes,
    opslimit: int = OPSLIMIT_INTERACTIVE,
    memlimit: int = MEMLIMIT_INTERACTIVE,
) -> bytes:
    """
    Hashes a password with a random salt, using the memory-hard
    argon2id construct and returning an ascii string that has all
    the needed info to check against a future password

    The default settings for opslimit and memlimit are those deemed
    correct for the interactive user login case.

    :param bytes password:
    :param int opslimit:
    :param int memlimit:
    :rtype: bytes

    .. versionadded:: 1.2
    """
    return nacl.bindings.crypto_pwhash_str_alg(
        password, opslimit, memlimit, ALG
    )