1# Copyright 2013 Donald Stufft and individual contributors
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15
16from __future__ import annotations
17
18import os
19from typing import TYPE_CHECKING, SupportsBytes
20
21import nacl.bindings
22from nacl import encoding
23
24if TYPE_CHECKING:
25 from typing_extensions import Self
26
27
28class EncryptedMessage(bytes):
29 """
30 A bytes subclass that holds a messaged that has been encrypted by a
31 :class:`SecretBox`.
32 """
33
34 _nonce: bytes
35 _ciphertext: bytes
36
37 @classmethod
38 def _from_parts(
39 cls,
40 nonce: bytes,
41 ciphertext: bytes,
42 combined: bytes,
43 ) -> Self:
44 obj = cls(combined)
45 obj._nonce = nonce
46 obj._ciphertext = ciphertext
47 return obj
48
49 @property
50 def nonce(self) -> bytes:
51 """
52 The nonce used during the encryption of the :class:`EncryptedMessage`.
53 """
54 return self._nonce
55
56 @property
57 def ciphertext(self) -> bytes:
58 """
59 The ciphertext contained within the :class:`EncryptedMessage`.
60 """
61 return self._ciphertext
62
63
64class StringFixer:
65 def __str__(self: SupportsBytes) -> str:
66 return str(self.__bytes__())
67
68
69def bytes_as_string(bytes_in: bytes) -> str:
70 return bytes_in.decode("ascii")
71
72
73def random(size: int = 32) -> bytes:
74 return os.urandom(size)
75
76
77def randombytes_deterministic(
78 size: int, seed: bytes, encoder: encoding.Encoder = encoding.RawEncoder
79) -> bytes:
80 """
81 Returns ``size`` number of deterministically generated pseudorandom bytes
82 from a seed
83
84 :param size: int
85 :param seed: bytes
86 :param encoder: The encoder class used to encode the produced bytes
87 :rtype: bytes
88 """
89 raw_data = nacl.bindings.randombytes_buf_deterministic(size, seed)
90
91 return encoder.encode(raw_data)