11import struct
2+ import secrets
23
3- __all__ = ("Encryption" , )
4+ __all__ = ("Decryption" , "Encryption" )
45
56from abc import ABC , abstractmethod
67
1112except ImportError :
1213 nacl_imported = False
1314
15+ try :
16+ from cryptography .hazmat .primitives .ciphers .aead import ChaCha20Poly1305 , AESGCM
17+
18+ cryptography_imported = True
19+ except ImportError :
20+ cryptography_imported = False
21+
1422
1523class Crypt (ABC ):
1624 SUPPORTED = (
25+ # todo: need deprecating
1726 "xsalsa20_poly1305_lite" ,
1827 "xsalsa20_poly1305_suffix" ,
1928 "xsalsa20_poly1305" ,
29+ "aead_xchacha20_poly1305_rtpsize" ,
30+ "aead_aes256_gcm_rtpsize" ,
2031 )
2132
2233 def __init__ (self , secret_key ) -> None :
23- if not nacl_imported :
34+ if not nacl_imported or not cryptography_imported :
2435 raise RuntimeError ("Please install interactions[voice] to use voice components." )
2536 self .box : secret .SecretBox = secret .SecretBox (bytes (secret_key ))
26-
2737 self ._xsalsa20_poly1305_lite_nonce : int = 0
2838
39+ self .xchacha20 = ChaCha20Poly1305 (bytes (secret_key ))
40+ self .aes_gcm = AESGCM (bytes (secret_key ))
41+
2942 @abstractmethod
3043 def xsalsa20_poly1305_lite (self , header : bytes , data ) -> bytes :
3144 raise NotImplementedError
@@ -38,6 +51,14 @@ def xsalsa20_poly1305_suffix(self, header: bytes, data) -> bytes:
3851 def xsalsa20_poly1305 (self , header : bytes , data ) -> bytes :
3952 raise NotImplementedError
4053
54+ @abstractmethod
55+ def aead_xchacha20_poly1305_rtpsize (self , header : bytes , data ) -> bytes :
56+ raise NotImplementedError
57+
58+ @abstractmethod
59+ def aead_aes256_gcm_rtpsize (self , header : bytes , data ) -> bytes :
60+ raise NotImplementedError
61+
4162
4263class Encryption (Crypt ):
4364 def encrypt (self , mode : str , header : bytes , data ) -> bytes :
@@ -48,6 +69,10 @@ def encrypt(self, mode: str, header: bytes, data) -> bytes:
4869 return self .xsalsa20_poly1305_suffix (header , data )
4970 case "xsalsa20_poly1305" :
5071 return self .xsalsa20_poly1305 (header , data )
72+ case "aead_xchacha20_poly1305_rtpsize" :
73+ return self .aead_xchacha20_poly1305_rtpsize (header , data )
74+ case "aead_aes256_gcm_rtpsize" :
75+ return self .aead_aes256_gcm_rtpsize (header , data )
5176 case _:
5277 raise RuntimeError (f"Unsupported encryption type requested: { mode } " )
5378
@@ -71,6 +96,22 @@ def xsalsa20_poly1305(self, header: bytes, data) -> bytes:
7196
7297 return header + self .box .encrypt (bytes (data ), bytes (nonce )).ciphertext
7398
99+ def aead_xchacha20_poly1305_rtpsize (self , header : bytes , data ) -> bytes :
100+ nonce_suffix = secrets .token_bytes (4 )
101+ nonce = bytearray (24 )
102+ nonce [:4 ] = nonce_suffix
103+ ciphertext = self .xchacha20 .encrypt (bytes (nonce ), bytes (data ), header )
104+
105+ return header + ciphertext + nonce_suffix
106+
107+ def aead_aes256_gcm_rtpsize (self , header : bytes , data ) -> bytes :
108+ nonce_suffix = secrets .token_bytes (4 )
109+ nonce = bytearray (12 )
110+ nonce [:4 ] = nonce_suffix
111+ ciphertext = self .aes_gcm .encrypt (bytes (nonce ), bytes (data ), header )
112+
113+ return header + ciphertext + nonce_suffix
114+
74115
75116class Decryption (Crypt ):
76117 def decrypt (self , mode : str , header : bytes , data ) -> bytes :
@@ -81,6 +122,10 @@ def decrypt(self, mode: str, header: bytes, data) -> bytes:
81122 return self .xsalsa20_poly1305_suffix (header , data )
82123 case "xsalsa20_poly1305" :
83124 return self .xsalsa20_poly1305 (header , data )
125+ case "aead_xchacha20_poly1305_rtpsize" :
126+ return self .aead_xchacha20_poly1305_rtpsize (header , data )
127+ case "aead_aes256_gcm_rtpsize" :
128+ return self .aead_aes256_gcm_rtpsize (header , data )
84129 case _:
85130 raise RuntimeError (f"Unsupported decryption type requested: { mode } " )
86131
@@ -98,11 +143,25 @@ def xsalsa20_poly1305_lite(self, header: bytes, data) -> bytes:
98143
99144 def xsalsa20_poly1305_suffix (self , header : bytes , data ) -> bytes :
100145 nonce = data [- 24 :]
101-
102146 return self .box .decrypt (bytes (data [:- 24 ]), bytes (nonce ))
103147
104148 def xsalsa20_poly1305 (self , header : bytes , data ) -> bytes :
105149 nonce = bytearray (24 )
106150 nonce [:12 ] = header
107-
108151 return self .box .decrypt (bytes (data ), bytes (nonce ))
152+
153+ def aead_xchacha20_poly1305_rtpsize (self , header : bytes , data ) -> bytes :
154+ nonce_suffix = data [- 4 :]
155+ ciphertext = data [:- 4 ]
156+ nonce = bytearray (24 )
157+ nonce [:4 ] = nonce_suffix
158+
159+ return self .xchacha20 .decrypt (bytes (nonce ), bytes (ciphertext ), header )
160+
161+ def aead_aes256_gcm_rtpsize (self , header : bytes , data ) -> bytes :
162+ nonce_suffix = data [- 4 :]
163+ ciphertext = data [:- 4 ]
164+ nonce = bytearray (12 )
165+ nonce [:4 ] = nonce_suffix
166+
167+ return self .aes_gcm .decrypt (bytes (nonce ), bytes (ciphertext ), header )
0 commit comments