Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/nacl/bindings/crypto_secretbox.py: 34%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

32 statements  

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 nacl import exceptions as exc 

17from nacl._sodium import ffi, lib 

18from nacl.exceptions import ensure 

19 

20 

21crypto_secretbox_KEYBYTES: int = lib.crypto_secretbox_keybytes() 

22crypto_secretbox_NONCEBYTES: int = lib.crypto_secretbox_noncebytes() 

23crypto_secretbox_ZEROBYTES: int = lib.crypto_secretbox_zerobytes() 

24crypto_secretbox_BOXZEROBYTES: int = lib.crypto_secretbox_boxzerobytes() 

25crypto_secretbox_MACBYTES: int = lib.crypto_secretbox_macbytes() 

26crypto_secretbox_MESSAGEBYTES_MAX: int = ( 

27 lib.crypto_secretbox_messagebytes_max() 

28) 

29 

30 

31def crypto_secretbox(message: bytes, nonce: bytes, key: bytes) -> bytes: 

32 """ 

33 Encrypts and returns the message ``message`` with the secret ``key`` and 

34 the nonce ``nonce``. 

35 

36 :param message: bytes 

37 :param nonce: bytes 

38 :param key: bytes 

39 :rtype: bytes 

40 """ 

41 if len(key) != crypto_secretbox_KEYBYTES: 

42 raise exc.ValueError("Invalid key") 

43 

44 if len(nonce) != crypto_secretbox_NONCEBYTES: 

45 raise exc.ValueError("Invalid nonce") 

46 

47 padded = b"\x00" * crypto_secretbox_ZEROBYTES + message 

48 ciphertext = ffi.new("unsigned char[]", len(padded)) 

49 

50 res = lib.crypto_secretbox(ciphertext, padded, len(padded), nonce, key) 

51 ensure(res == 0, "Encryption failed", raising=exc.CryptoError) 

52 

53 ciphertext = ffi.buffer(ciphertext, len(padded)) 

54 return ciphertext[crypto_secretbox_BOXZEROBYTES:] 

55 

56 

57def crypto_secretbox_open( 

58 ciphertext: bytes, nonce: bytes, key: bytes 

59) -> bytes: 

60 """ 

61 Decrypt and returns the encrypted message ``ciphertext`` with the secret 

62 ``key`` and the nonce ``nonce``. 

63 

64 :param ciphertext: bytes 

65 :param nonce: bytes 

66 :param key: bytes 

67 :rtype: bytes 

68 """ 

69 if len(key) != crypto_secretbox_KEYBYTES: 

70 raise exc.ValueError("Invalid key") 

71 

72 if len(nonce) != crypto_secretbox_NONCEBYTES: 

73 raise exc.ValueError("Invalid nonce") 

74 

75 padded = b"\x00" * crypto_secretbox_BOXZEROBYTES + ciphertext 

76 plaintext = ffi.new("unsigned char[]", len(padded)) 

77 

78 res = lib.crypto_secretbox_open(plaintext, padded, len(padded), nonce, key) 

79 ensure( 

80 res == 0, 

81 "Decryption failed. Ciphertext failed verification", 

82 raising=exc.CryptoError, 

83 ) 

84 

85 plaintext = ffi.buffer(plaintext, len(padded)) 

86 return plaintext[crypto_secretbox_ZEROBYTES:]