Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/PyNaCl-1.6.2-py3.11-linux-x86_64.egg/nacl/bindings/crypto_secretbox.py: 23%

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

57 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 

20crypto_secretbox_KEYBYTES: int = lib.crypto_secretbox_keybytes() 

21crypto_secretbox_NONCEBYTES: int = lib.crypto_secretbox_noncebytes() 

22crypto_secretbox_ZEROBYTES: int = lib.crypto_secretbox_zerobytes() 

23crypto_secretbox_BOXZEROBYTES: int = lib.crypto_secretbox_boxzerobytes() 

24crypto_secretbox_MACBYTES: int = lib.crypto_secretbox_macbytes() 

25crypto_secretbox_MESSAGEBYTES_MAX: int = ( 

26 lib.crypto_secretbox_messagebytes_max() 

27) 

28 

29 

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

31 """ 

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

33 the nonce ``nonce``. 

34 

35 :param message: bytes 

36 :param nonce: bytes 

37 :param key: bytes 

38 :rtype: bytes 

39 """ 

40 if len(key) != crypto_secretbox_KEYBYTES: 

41 raise exc.ValueError("Invalid key") 

42 

43 if len(nonce) != crypto_secretbox_NONCEBYTES: 

44 raise exc.ValueError("Invalid nonce") 

45 

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

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

48 

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

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

51 

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

53 return ciphertext[crypto_secretbox_BOXZEROBYTES:] 

54 

55 

56def crypto_secretbox_open( 

57 ciphertext: bytes, nonce: bytes, key: bytes 

58) -> bytes: 

59 """ 

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

61 ``key`` and the nonce ``nonce``. 

62 

63 :param ciphertext: bytes 

64 :param nonce: bytes 

65 :param key: bytes 

66 :rtype: bytes 

67 """ 

68 if len(key) != crypto_secretbox_KEYBYTES: 

69 raise exc.ValueError("Invalid key") 

70 

71 if len(nonce) != crypto_secretbox_NONCEBYTES: 

72 raise exc.ValueError("Invalid nonce") 

73 

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

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

76 

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

78 ensure( 

79 res == 0, 

80 "Decryption failed. Ciphertext failed verification", 

81 raising=exc.CryptoError, 

82 ) 

83 

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

85 return plaintext[crypto_secretbox_ZEROBYTES:] 

86 

87 

88def crypto_secretbox_easy(message: bytes, nonce: bytes, key: bytes) -> bytes: 

89 """ 

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

91 the nonce ``nonce``. 

92 

93 :param message: bytes 

94 :param nonce: bytes 

95 :param key: bytes 

96 :rtype: bytes 

97 """ 

98 if len(key) != crypto_secretbox_KEYBYTES: 

99 raise exc.ValueError("Invalid key") 

100 

101 if len(nonce) != crypto_secretbox_NONCEBYTES: 

102 raise exc.ValueError("Invalid nonce") 

103 

104 _mlen = len(message) 

105 _clen = crypto_secretbox_MACBYTES + _mlen 

106 

107 ciphertext = ffi.new("unsigned char[]", _clen) 

108 

109 res = lib.crypto_secretbox_easy(ciphertext, message, _mlen, nonce, key) 

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

111 

112 ciphertext = ffi.buffer(ciphertext, _clen) 

113 return ciphertext[:] 

114 

115 

116def crypto_secretbox_open_easy( 

117 ciphertext: bytes, nonce: bytes, key: bytes 

118) -> bytes: 

119 """ 

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

121 ``key`` and the nonce ``nonce``. 

122 

123 :param ciphertext: bytes 

124 :param nonce: bytes 

125 :param key: bytes 

126 :rtype: bytes 

127 """ 

128 if len(key) != crypto_secretbox_KEYBYTES: 

129 raise exc.ValueError("Invalid key") 

130 

131 if len(nonce) != crypto_secretbox_NONCEBYTES: 

132 raise exc.ValueError("Invalid nonce") 

133 

134 _clen = len(ciphertext) 

135 

136 ensure( 

137 _clen >= crypto_secretbox_MACBYTES, 

138 f"Input ciphertext must be at least {crypto_secretbox_MACBYTES} long", 

139 raising=exc.TypeError, 

140 ) 

141 

142 _mlen = _clen - crypto_secretbox_MACBYTES 

143 

144 plaintext = ffi.new("unsigned char[]", max(1, _mlen)) 

145 

146 res = lib.crypto_secretbox_open_easy( 

147 plaintext, ciphertext, _clen, nonce, key 

148 ) 

149 ensure( 

150 res == 0, 

151 "Decryption failed. Ciphertext failed verification", 

152 raising=exc.CryptoError, 

153 ) 

154 

155 plaintext = ffi.buffer(plaintext, _mlen) 

156 return plaintext[:]