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_aead.py: 20%

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

260 statements  

1# Copyright 2017 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. 

14from __future__ import annotations 

15 

16from nacl import exceptions as exc 

17from nacl._sodium import ffi, lib 

18from nacl.exceptions import ensure 

19 

20""" 

21Implementations of authenticated encription with associated data (*AEAD*) 

22constructions building on the chacha20 stream cipher and the poly1305 

23authenticator 

24""" 

25 

26crypto_aead_chacha20poly1305_ietf_KEYBYTES: int = ( 

27 lib.crypto_aead_chacha20poly1305_ietf_keybytes() 

28) 

29crypto_aead_chacha20poly1305_ietf_NSECBYTES: int = ( 

30 lib.crypto_aead_chacha20poly1305_ietf_nsecbytes() 

31) 

32crypto_aead_chacha20poly1305_ietf_NPUBBYTES: int = ( 

33 lib.crypto_aead_chacha20poly1305_ietf_npubbytes() 

34) 

35crypto_aead_chacha20poly1305_ietf_ABYTES: int = ( 

36 lib.crypto_aead_chacha20poly1305_ietf_abytes() 

37) 

38crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX: int = ( 

39 lib.crypto_aead_chacha20poly1305_ietf_messagebytes_max() 

40) 

41_aead_chacha20poly1305_ietf_CRYPTBYTES_MAX = ( 

42 crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX 

43 + crypto_aead_chacha20poly1305_ietf_ABYTES 

44) 

45 

46crypto_aead_chacha20poly1305_KEYBYTES: int = ( 

47 lib.crypto_aead_chacha20poly1305_keybytes() 

48) 

49crypto_aead_chacha20poly1305_NSECBYTES: int = ( 

50 lib.crypto_aead_chacha20poly1305_nsecbytes() 

51) 

52crypto_aead_chacha20poly1305_NPUBBYTES: int = ( 

53 lib.crypto_aead_chacha20poly1305_npubbytes() 

54) 

55crypto_aead_chacha20poly1305_ABYTES: int = ( 

56 lib.crypto_aead_chacha20poly1305_abytes() 

57) 

58crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX: int = ( 

59 lib.crypto_aead_chacha20poly1305_messagebytes_max() 

60) 

61_aead_chacha20poly1305_CRYPTBYTES_MAX = ( 

62 crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX 

63 + crypto_aead_chacha20poly1305_ABYTES 

64) 

65 

66crypto_aead_xchacha20poly1305_ietf_KEYBYTES: int = ( 

67 lib.crypto_aead_xchacha20poly1305_ietf_keybytes() 

68) 

69crypto_aead_xchacha20poly1305_ietf_NSECBYTES: int = ( 

70 lib.crypto_aead_xchacha20poly1305_ietf_nsecbytes() 

71) 

72crypto_aead_xchacha20poly1305_ietf_NPUBBYTES: int = ( 

73 lib.crypto_aead_xchacha20poly1305_ietf_npubbytes() 

74) 

75crypto_aead_xchacha20poly1305_ietf_ABYTES: int = ( 

76 lib.crypto_aead_xchacha20poly1305_ietf_abytes() 

77) 

78crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX: int = ( 

79 lib.crypto_aead_xchacha20poly1305_ietf_messagebytes_max() 

80) 

81_aead_xchacha20poly1305_ietf_CRYPTBYTES_MAX = ( 

82 crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX 

83 + crypto_aead_xchacha20poly1305_ietf_ABYTES 

84) 

85 

86crypto_aead_aegis256_KEYBYTES: int = lib.crypto_aead_aegis256_keybytes() 

87crypto_aead_aegis256_NSECBYTES: int = lib.crypto_aead_aegis256_nsecbytes() 

88crypto_aead_aegis256_NPUBBYTES: int = lib.crypto_aead_aegis256_npubbytes() 

89crypto_aead_aegis256_ABYTES: int = lib.crypto_aead_aegis256_abytes() 

90crypto_aead_aegis256_MESSAGEBYTES_MAX: int = ( 

91 lib.crypto_aead_aegis256_messagebytes_max() 

92) 

93_aead_aegis256_CRYPTBYTES_MAX = ( 

94 crypto_aead_aegis256_MESSAGEBYTES_MAX + crypto_aead_aegis256_ABYTES 

95) 

96 

97crypto_aead_aegis128l_KEYBYTES: int = lib.crypto_aead_aegis128l_keybytes() 

98crypto_aead_aegis128l_NSECBYTES: int = lib.crypto_aead_aegis128l_nsecbytes() 

99crypto_aead_aegis128l_NPUBBYTES: int = lib.crypto_aead_aegis128l_npubbytes() 

100crypto_aead_aegis128l_ABYTES: int = lib.crypto_aead_aegis128l_abytes() 

101crypto_aead_aegis128l_MESSAGEBYTES_MAX: int = ( 

102 lib.crypto_aead_aegis128l_messagebytes_max() 

103) 

104_aead_aegis256_CRYPTBYTES_MAX = ( 

105 crypto_aead_aegis128l_MESSAGEBYTES_MAX + crypto_aead_aegis128l_ABYTES 

106) 

107 

108crypto_aead_aes256gcm_KEYBYTES: int = lib.crypto_aead_aes256gcm_keybytes() 

109crypto_aead_aes256gcm_NSECBYTES: int = lib.crypto_aead_aes256gcm_nsecbytes() 

110crypto_aead_aes256gcm_NPUBBYTES: int = lib.crypto_aead_aes256gcm_npubbytes() 

111crypto_aead_aes256gcm_ABYTES: int = lib.crypto_aead_aes256gcm_abytes() 

112crypto_aead_aes256gcm_MESSAGEBYTES_MAX: int = ( 

113 lib.crypto_aead_aes256gcm_messagebytes_max() 

114) 

115_aead_aegis256_CRYPTBYTES_MAX = ( 

116 crypto_aead_aes256gcm_MESSAGEBYTES_MAX + crypto_aead_aes256gcm_ABYTES 

117) 

118 

119 

120def crypto_aead_chacha20poly1305_ietf_encrypt( 

121 message: bytes, aad: bytes | None, nonce: bytes, key: bytes 

122) -> bytes: 

123 """ 

124 Encrypt the given ``message`` using the IETF ratified chacha20poly1305 

125 construction described in RFC7539. 

126 

127 :param message: 

128 :type message: bytes 

129 :param aad: 

130 :type aad: Optional[bytes] 

131 :param nonce: 

132 :type nonce: bytes 

133 :param key: 

134 :type key: bytes 

135 :return: authenticated ciphertext 

136 :rtype: bytes 

137 """ 

138 ensure( 

139 isinstance(message, bytes), 

140 "Input message type must be bytes", 

141 raising=exc.TypeError, 

142 ) 

143 

144 mlen = len(message) 

145 

146 ensure( 

147 mlen <= crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX, 

148 f"Message must be at most {crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX} bytes long", 

149 raising=exc.ValueError, 

150 ) 

151 

152 ensure( 

153 isinstance(aad, bytes) or (aad is None), 

154 "Additional data must be bytes or None", 

155 raising=exc.TypeError, 

156 ) 

157 

158 ensure( 

159 isinstance(nonce, bytes) 

160 and len(nonce) == crypto_aead_chacha20poly1305_ietf_NPUBBYTES, 

161 f"Nonce must be a {crypto_aead_chacha20poly1305_ietf_NPUBBYTES} bytes long bytes sequence", 

162 raising=exc.TypeError, 

163 ) 

164 

165 ensure( 

166 isinstance(key, bytes) 

167 and len(key) == crypto_aead_chacha20poly1305_ietf_KEYBYTES, 

168 f"Key must be a {crypto_aead_chacha20poly1305_ietf_KEYBYTES} bytes long bytes sequence", 

169 raising=exc.TypeError, 

170 ) 

171 

172 if aad: 

173 _aad = aad 

174 aalen = len(aad) 

175 else: 

176 _aad = ffi.NULL 

177 aalen = 0 

178 

179 mxout = mlen + crypto_aead_chacha20poly1305_ietf_ABYTES 

180 

181 clen = ffi.new("unsigned long long *") 

182 

183 ciphertext = ffi.new("unsigned char[]", mxout) 

184 

185 res = lib.crypto_aead_chacha20poly1305_ietf_encrypt( 

186 ciphertext, clen, message, mlen, _aad, aalen, ffi.NULL, nonce, key 

187 ) 

188 

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

190 return ffi.buffer(ciphertext, clen[0])[:] 

191 

192 

193def crypto_aead_chacha20poly1305_ietf_decrypt( 

194 ciphertext: bytes, aad: bytes | None, nonce: bytes, key: bytes 

195) -> bytes: 

196 """ 

197 Decrypt the given ``ciphertext`` using the IETF ratified chacha20poly1305 

198 construction described in RFC7539. 

199 

200 :param ciphertext: 

201 :type ciphertext: bytes 

202 :param aad: 

203 :type aad: Optional[bytes] 

204 :param nonce: 

205 :type nonce: bytes 

206 :param key: 

207 :type key: bytes 

208 :return: message 

209 :rtype: bytes 

210 """ 

211 ensure( 

212 isinstance(ciphertext, bytes), 

213 "Input ciphertext type must be bytes", 

214 raising=exc.TypeError, 

215 ) 

216 

217 clen = len(ciphertext) 

218 

219 ensure( 

220 clen <= _aead_chacha20poly1305_ietf_CRYPTBYTES_MAX, 

221 f"Ciphertext must be at most {_aead_chacha20poly1305_ietf_CRYPTBYTES_MAX} bytes long", 

222 raising=exc.ValueError, 

223 ) 

224 

225 ensure( 

226 isinstance(aad, bytes) or (aad is None), 

227 "Additional data must be bytes or None", 

228 raising=exc.TypeError, 

229 ) 

230 

231 ensure( 

232 isinstance(nonce, bytes) 

233 and len(nonce) == crypto_aead_chacha20poly1305_ietf_NPUBBYTES, 

234 f"Nonce must be a {crypto_aead_chacha20poly1305_ietf_NPUBBYTES} bytes long bytes sequence", 

235 raising=exc.TypeError, 

236 ) 

237 

238 ensure( 

239 isinstance(key, bytes) 

240 and len(key) == crypto_aead_chacha20poly1305_ietf_KEYBYTES, 

241 f"Key must be a {crypto_aead_chacha20poly1305_ietf_KEYBYTES} bytes long bytes sequence", 

242 raising=exc.TypeError, 

243 ) 

244 

245 mxout = clen - crypto_aead_chacha20poly1305_ietf_ABYTES 

246 

247 mlen = ffi.new("unsigned long long *") 

248 message = ffi.new("unsigned char[]", mxout) 

249 

250 if aad: 

251 _aad = aad 

252 aalen = len(aad) 

253 else: 

254 _aad = ffi.NULL 

255 aalen = 0 

256 

257 res = lib.crypto_aead_chacha20poly1305_ietf_decrypt( 

258 message, mlen, ffi.NULL, ciphertext, clen, _aad, aalen, nonce, key 

259 ) 

260 

261 ensure(res == 0, "Decryption failed.", raising=exc.CryptoError) 

262 

263 return ffi.buffer(message, mlen[0])[:] 

264 

265 

266def crypto_aead_chacha20poly1305_encrypt( 

267 message: bytes, aad: bytes | None, nonce: bytes, key: bytes 

268) -> bytes: 

269 """ 

270 Encrypt the given ``message`` using the "legacy" construction 

271 described in draft-agl-tls-chacha20poly1305. 

272 

273 :param message: 

274 :type message: bytes 

275 :param aad: 

276 :type aad: Optional[bytes] 

277 :param nonce: 

278 :type nonce: bytes 

279 :param key: 

280 :type key: bytes 

281 :return: authenticated ciphertext 

282 :rtype: bytes 

283 """ 

284 ensure( 

285 isinstance(message, bytes), 

286 "Input message type must be bytes", 

287 raising=exc.TypeError, 

288 ) 

289 

290 mlen = len(message) 

291 

292 ensure( 

293 mlen <= crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX, 

294 f"Message must be at most {crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX} bytes long", 

295 raising=exc.ValueError, 

296 ) 

297 

298 ensure( 

299 isinstance(aad, bytes) or (aad is None), 

300 "Additional data must be bytes or None", 

301 raising=exc.TypeError, 

302 ) 

303 

304 ensure( 

305 isinstance(nonce, bytes) 

306 and len(nonce) == crypto_aead_chacha20poly1305_NPUBBYTES, 

307 f"Nonce must be a {crypto_aead_chacha20poly1305_NPUBBYTES} bytes long bytes sequence", 

308 raising=exc.TypeError, 

309 ) 

310 

311 ensure( 

312 isinstance(key, bytes) 

313 and len(key) == crypto_aead_chacha20poly1305_KEYBYTES, 

314 f"Key must be a {crypto_aead_chacha20poly1305_KEYBYTES} bytes long bytes sequence", 

315 raising=exc.TypeError, 

316 ) 

317 

318 if aad: 

319 _aad = aad 

320 aalen = len(aad) 

321 else: 

322 _aad = ffi.NULL 

323 aalen = 0 

324 

325 mxout = mlen + crypto_aead_chacha20poly1305_ietf_ABYTES 

326 

327 clen = ffi.new("unsigned long long *") 

328 

329 ciphertext = ffi.new("unsigned char[]", mxout) 

330 

331 res = lib.crypto_aead_chacha20poly1305_encrypt( 

332 ciphertext, clen, message, mlen, _aad, aalen, ffi.NULL, nonce, key 

333 ) 

334 

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

336 return ffi.buffer(ciphertext, clen[0])[:] 

337 

338 

339def crypto_aead_chacha20poly1305_decrypt( 

340 ciphertext: bytes, aad: bytes | None, nonce: bytes, key: bytes 

341) -> bytes: 

342 """ 

343 Decrypt the given ``ciphertext`` using the "legacy" construction 

344 described in draft-agl-tls-chacha20poly1305. 

345 

346 :param ciphertext: authenticated ciphertext 

347 :type ciphertext: bytes 

348 :param aad: 

349 :type aad: Optional[bytes] 

350 :param nonce: 

351 :type nonce: bytes 

352 :param key: 

353 :type key: bytes 

354 :return: message 

355 :rtype: bytes 

356 """ 

357 ensure( 

358 isinstance(ciphertext, bytes), 

359 "Input ciphertext type must be bytes", 

360 raising=exc.TypeError, 

361 ) 

362 

363 clen = len(ciphertext) 

364 

365 ensure( 

366 clen <= _aead_chacha20poly1305_CRYPTBYTES_MAX, 

367 f"Ciphertext must be at most {_aead_chacha20poly1305_CRYPTBYTES_MAX} bytes long", 

368 raising=exc.ValueError, 

369 ) 

370 

371 ensure( 

372 isinstance(aad, bytes) or (aad is None), 

373 "Additional data must be bytes or None", 

374 raising=exc.TypeError, 

375 ) 

376 

377 ensure( 

378 isinstance(nonce, bytes) 

379 and len(nonce) == crypto_aead_chacha20poly1305_NPUBBYTES, 

380 f"Nonce must be a {crypto_aead_chacha20poly1305_NPUBBYTES} bytes long bytes sequence", 

381 raising=exc.TypeError, 

382 ) 

383 

384 ensure( 

385 isinstance(key, bytes) 

386 and len(key) == crypto_aead_chacha20poly1305_KEYBYTES, 

387 f"Key must be a {crypto_aead_chacha20poly1305_KEYBYTES} bytes long bytes sequence", 

388 raising=exc.TypeError, 

389 ) 

390 

391 mxout = clen - crypto_aead_chacha20poly1305_ABYTES 

392 

393 mlen = ffi.new("unsigned long long *") 

394 message = ffi.new("unsigned char[]", mxout) 

395 

396 if aad: 

397 _aad = aad 

398 aalen = len(aad) 

399 else: 

400 _aad = ffi.NULL 

401 aalen = 0 

402 

403 res = lib.crypto_aead_chacha20poly1305_decrypt( 

404 message, mlen, ffi.NULL, ciphertext, clen, _aad, aalen, nonce, key 

405 ) 

406 

407 ensure(res == 0, "Decryption failed.", raising=exc.CryptoError) 

408 

409 return ffi.buffer(message, mlen[0])[:] 

410 

411 

412def crypto_aead_xchacha20poly1305_ietf_encrypt( 

413 message: bytes, aad: bytes | None, nonce: bytes, key: bytes 

414) -> bytes: 

415 """ 

416 Encrypt the given ``message`` using the long-nonces xchacha20poly1305 

417 construction. 

418 

419 :param message: 

420 :type message: bytes 

421 :param aad: 

422 :type aad: Optional[bytes] 

423 :param nonce: 

424 :type nonce: bytes 

425 :param key: 

426 :type key: bytes 

427 :return: authenticated ciphertext 

428 :rtype: bytes 

429 """ 

430 ensure( 

431 isinstance(message, bytes), 

432 "Input message type must be bytes", 

433 raising=exc.TypeError, 

434 ) 

435 

436 mlen = len(message) 

437 

438 ensure( 

439 mlen <= crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX, 

440 f"Message must be at most {crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX} bytes long", 

441 raising=exc.ValueError, 

442 ) 

443 

444 ensure( 

445 isinstance(aad, bytes) or (aad is None), 

446 "Additional data must be bytes or None", 

447 raising=exc.TypeError, 

448 ) 

449 

450 ensure( 

451 isinstance(nonce, bytes) 

452 and len(nonce) == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES, 

453 f"Nonce must be a {crypto_aead_xchacha20poly1305_ietf_NPUBBYTES} bytes long bytes sequence", 

454 raising=exc.TypeError, 

455 ) 

456 

457 ensure( 

458 isinstance(key, bytes) 

459 and len(key) == crypto_aead_xchacha20poly1305_ietf_KEYBYTES, 

460 f"Key must be a {crypto_aead_xchacha20poly1305_ietf_KEYBYTES} bytes long bytes sequence", 

461 raising=exc.TypeError, 

462 ) 

463 

464 if aad: 

465 _aad = aad 

466 aalen = len(aad) 

467 else: 

468 _aad = ffi.NULL 

469 aalen = 0 

470 

471 mxout = mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES 

472 

473 clen = ffi.new("unsigned long long *") 

474 

475 ciphertext = ffi.new("unsigned char[]", mxout) 

476 

477 res = lib.crypto_aead_xchacha20poly1305_ietf_encrypt( 

478 ciphertext, clen, message, mlen, _aad, aalen, ffi.NULL, nonce, key 

479 ) 

480 

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

482 return ffi.buffer(ciphertext, clen[0])[:] 

483 

484 

485def crypto_aead_xchacha20poly1305_ietf_decrypt( 

486 ciphertext: bytes, aad: bytes | None, nonce: bytes, key: bytes 

487) -> bytes: 

488 """ 

489 Decrypt the given ``ciphertext`` using the long-nonces xchacha20poly1305 

490 construction. 

491 

492 :param ciphertext: authenticated ciphertext 

493 :type ciphertext: bytes 

494 :param aad: 

495 :type aad: Optional[bytes] 

496 :param nonce: 

497 :type nonce: bytes 

498 :param key: 

499 :type key: bytes 

500 :return: message 

501 :rtype: bytes 

502 """ 

503 ensure( 

504 isinstance(ciphertext, bytes), 

505 "Input ciphertext type must be bytes", 

506 raising=exc.TypeError, 

507 ) 

508 

509 clen = len(ciphertext) 

510 

511 ensure( 

512 clen <= _aead_xchacha20poly1305_ietf_CRYPTBYTES_MAX, 

513 f"Ciphertext must be at most {_aead_xchacha20poly1305_ietf_CRYPTBYTES_MAX} bytes long", 

514 raising=exc.ValueError, 

515 ) 

516 

517 ensure( 

518 isinstance(aad, bytes) or (aad is None), 

519 "Additional data must be bytes or None", 

520 raising=exc.TypeError, 

521 ) 

522 

523 ensure( 

524 isinstance(nonce, bytes) 

525 and len(nonce) == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES, 

526 f"Nonce must be a {crypto_aead_xchacha20poly1305_ietf_NPUBBYTES} bytes long bytes sequence", 

527 raising=exc.TypeError, 

528 ) 

529 

530 ensure( 

531 isinstance(key, bytes) 

532 and len(key) == crypto_aead_xchacha20poly1305_ietf_KEYBYTES, 

533 f"Key must be a {crypto_aead_xchacha20poly1305_ietf_KEYBYTES} bytes long bytes sequence", 

534 raising=exc.TypeError, 

535 ) 

536 

537 mxout = clen - crypto_aead_xchacha20poly1305_ietf_ABYTES 

538 mlen = ffi.new("unsigned long long *") 

539 message = ffi.new("unsigned char[]", mxout) 

540 

541 if aad: 

542 _aad = aad 

543 aalen = len(aad) 

544 else: 

545 _aad = ffi.NULL 

546 aalen = 0 

547 

548 res = lib.crypto_aead_xchacha20poly1305_ietf_decrypt( 

549 message, mlen, ffi.NULL, ciphertext, clen, _aad, aalen, nonce, key 

550 ) 

551 

552 ensure(res == 0, "Decryption failed.", raising=exc.CryptoError) 

553 

554 return ffi.buffer(message, mlen[0])[:] 

555 

556 

557def crypto_aead_aegis256_encrypt( 

558 message: bytes, aad: bytes | None, nonce: bytes, key: bytes 

559) -> bytes: 

560 """ 

561 Encrypt the given ``message`` using the AEGIS-256 

562 construction. 

563 

564 :param message: 

565 :type message: bytes 

566 :param aad: 

567 :type aad: Optional[bytes] 

568 :param nonce: 

569 :type nonce: bytes 

570 :param key: 

571 :type key: bytes 

572 :return: authenticated ciphertext 

573 :rtype: bytes 

574 """ 

575 ensure( 

576 isinstance(message, bytes), 

577 "Input message type must be bytes", 

578 raising=exc.TypeError, 

579 ) 

580 

581 mlen = len(message) 

582 

583 ensure( 

584 mlen <= crypto_aead_aegis256_MESSAGEBYTES_MAX, 

585 f"Message must be at most {crypto_aead_aegis256_MESSAGEBYTES_MAX} bytes long", 

586 raising=exc.ValueError, 

587 ) 

588 

589 ensure( 

590 isinstance(aad, bytes) or (aad is None), 

591 "Additional data must be bytes or None", 

592 raising=exc.TypeError, 

593 ) 

594 

595 ensure( 

596 isinstance(nonce, bytes) 

597 and len(nonce) == crypto_aead_aegis256_NPUBBYTES, 

598 f"Nonce must be a {crypto_aead_aegis256_NPUBBYTES} bytes long bytes sequence", 

599 raising=exc.TypeError, 

600 ) 

601 

602 ensure( 

603 isinstance(key, bytes) and len(key) == crypto_aead_aegis256_KEYBYTES, 

604 f"Key must be a {crypto_aead_aegis256_KEYBYTES} bytes long bytes sequence", 

605 raising=exc.TypeError, 

606 ) 

607 

608 if aad: 

609 _aad = aad 

610 aalen = len(aad) 

611 else: 

612 _aad = ffi.NULL 

613 aalen = 0 

614 

615 mxout = mlen + crypto_aead_aegis256_ABYTES 

616 

617 clen = ffi.new("unsigned long long *") 

618 

619 ciphertext = ffi.new("unsigned char[]", mxout) 

620 

621 res = lib.crypto_aead_aegis256_encrypt( 

622 ciphertext, clen, message, mlen, _aad, aalen, ffi.NULL, nonce, key 

623 ) 

624 

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

626 return ffi.buffer(ciphertext, clen[0])[:] 

627 

628 

629def crypto_aead_aegis256_decrypt( 

630 ciphertext: bytes, aad: bytes | None, nonce: bytes, key: bytes 

631) -> bytes: 

632 """ 

633 Decrypt the given ``ciphertext`` using the AEGIS-256 

634 construction. 

635 

636 :param ciphertext: authenticated ciphertext 

637 :type ciphertext: bytes 

638 :param aad: 

639 :type aad: Optional[bytes] 

640 :param nonce: 

641 :type nonce: bytes 

642 :param key: 

643 :type key: bytes 

644 :return: message 

645 :rtype: bytes 

646 """ 

647 ensure( 

648 isinstance(ciphertext, bytes), 

649 "Input ciphertext type must be bytes", 

650 raising=exc.TypeError, 

651 ) 

652 

653 clen = len(ciphertext) 

654 

655 ensure( 

656 clen <= _aead_aegis256_CRYPTBYTES_MAX, 

657 f"Ciphertext must be at most {_aead_aegis256_CRYPTBYTES_MAX} bytes long", 

658 raising=exc.ValueError, 

659 ) 

660 

661 ensure( 

662 isinstance(aad, bytes) or (aad is None), 

663 "Additional data must be bytes or None", 

664 raising=exc.TypeError, 

665 ) 

666 

667 ensure( 

668 isinstance(nonce, bytes) 

669 and len(nonce) == crypto_aead_aegis256_NPUBBYTES, 

670 f"Nonce must be a {crypto_aead_aegis256_NPUBBYTES} bytes long bytes sequence", 

671 raising=exc.TypeError, 

672 ) 

673 

674 ensure( 

675 isinstance(key, bytes) and len(key) == crypto_aead_aegis256_KEYBYTES, 

676 f"Key must be a {crypto_aead_aegis256_KEYBYTES} bytes long bytes sequence", 

677 raising=exc.TypeError, 

678 ) 

679 

680 mxout = clen - crypto_aead_aegis256_ABYTES 

681 mlen = ffi.new("unsigned long long *") 

682 message = ffi.new("unsigned char[]", mxout) 

683 

684 if aad: 

685 _aad = aad 

686 aalen = len(aad) 

687 else: 

688 _aad = ffi.NULL 

689 aalen = 0 

690 

691 res = lib.crypto_aead_aegis256_decrypt( 

692 message, mlen, ffi.NULL, ciphertext, clen, _aad, aalen, nonce, key 

693 ) 

694 

695 ensure(res == 0, "Decryption failed.", raising=exc.CryptoError) 

696 

697 return ffi.buffer(message, mlen[0])[:] 

698 

699 

700def crypto_aead_aegis128l_encrypt( 

701 message: bytes, aad: bytes | None, nonce: bytes, key: bytes 

702) -> bytes: 

703 """ 

704 Encrypt the given ``message`` using the AEGIS-128L 

705 construction. 

706 

707 :param message: 

708 :type message: bytes 

709 :param aad: 

710 :type aad: Optional[bytes] 

711 :param nonce: 

712 :type nonce: bytes 

713 :param key: 

714 :type key: bytes 

715 :return: authenticated ciphertext 

716 :rtype: bytes 

717 """ 

718 ensure( 

719 isinstance(message, bytes), 

720 "Input message type must be bytes", 

721 raising=exc.TypeError, 

722 ) 

723 

724 mlen = len(message) 

725 

726 ensure( 

727 mlen <= crypto_aead_aegis128l_MESSAGEBYTES_MAX, 

728 f"Message must be at most {crypto_aead_aegis128l_MESSAGEBYTES_MAX} bytes long", 

729 raising=exc.ValueError, 

730 ) 

731 

732 ensure( 

733 isinstance(aad, bytes) or (aad is None), 

734 "Additional data must be bytes or None", 

735 raising=exc.TypeError, 

736 ) 

737 

738 ensure( 

739 isinstance(nonce, bytes) 

740 and len(nonce) == crypto_aead_aegis128l_NPUBBYTES, 

741 f"Nonce must be a {crypto_aead_aegis128l_NPUBBYTES} bytes long bytes sequence", 

742 raising=exc.TypeError, 

743 ) 

744 

745 ensure( 

746 isinstance(key, bytes) and len(key) == crypto_aead_aegis128l_KEYBYTES, 

747 f"Key must be a {crypto_aead_aegis128l_KEYBYTES} bytes long bytes sequence", 

748 raising=exc.TypeError, 

749 ) 

750 

751 if aad: 

752 _aad = aad 

753 aalen = len(aad) 

754 else: 

755 _aad = ffi.NULL 

756 aalen = 0 

757 

758 mxout = mlen + crypto_aead_aegis128l_ABYTES 

759 

760 clen = ffi.new("unsigned long long *") 

761 

762 ciphertext = ffi.new("unsigned char[]", mxout) 

763 

764 res = lib.crypto_aead_aegis128l_encrypt( 

765 ciphertext, clen, message, mlen, _aad, aalen, ffi.NULL, nonce, key 

766 ) 

767 

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

769 return ffi.buffer(ciphertext, clen[0])[:] 

770 

771 

772def crypto_aead_aegis128l_decrypt( 

773 ciphertext: bytes, aad: bytes | None, nonce: bytes, key: bytes 

774) -> bytes: 

775 """ 

776 Decrypt the given ``ciphertext`` using the AEGIS-128L 

777 construction. 

778 

779 :param ciphertext: authenticated ciphertext 

780 :type ciphertext: bytes 

781 :param aad: 

782 :type aad: Optional[bytes] 

783 :param nonce: 

784 :type nonce: bytes 

785 :param key: 

786 :type key: bytes 

787 :return: message 

788 :rtype: bytes 

789 """ 

790 ensure( 

791 isinstance(ciphertext, bytes), 

792 "Input ciphertext type must be bytes", 

793 raising=exc.TypeError, 

794 ) 

795 

796 clen = len(ciphertext) 

797 

798 ensure( 

799 clen <= _aead_aegis256_CRYPTBYTES_MAX, 

800 f"Ciphertext must be at most {_aead_aegis256_CRYPTBYTES_MAX} bytes long", 

801 raising=exc.ValueError, 

802 ) 

803 

804 ensure( 

805 isinstance(aad, bytes) or (aad is None), 

806 "Additional data must be bytes or None", 

807 raising=exc.TypeError, 

808 ) 

809 

810 ensure( 

811 isinstance(nonce, bytes) 

812 and len(nonce) == crypto_aead_aegis128l_NPUBBYTES, 

813 f"Nonce must be a {crypto_aead_aegis128l_NPUBBYTES} bytes long bytes sequence", 

814 raising=exc.TypeError, 

815 ) 

816 

817 ensure( 

818 isinstance(key, bytes) and len(key) == crypto_aead_aegis128l_KEYBYTES, 

819 f"Key must be a {crypto_aead_aegis128l_KEYBYTES} bytes long bytes sequence", 

820 raising=exc.TypeError, 

821 ) 

822 

823 mxout = clen - crypto_aead_aegis128l_ABYTES 

824 mlen = ffi.new("unsigned long long *") 

825 message = ffi.new("unsigned char[]", mxout) 

826 

827 if aad: 

828 _aad = aad 

829 aalen = len(aad) 

830 else: 

831 _aad = ffi.NULL 

832 aalen = 0 

833 

834 res = lib.crypto_aead_aegis128l_decrypt( 

835 message, mlen, ffi.NULL, ciphertext, clen, _aad, aalen, nonce, key 

836 ) 

837 

838 ensure(res == 0, "Decryption failed.", raising=exc.CryptoError) 

839 

840 return ffi.buffer(message, mlen[0])[:] 

841 

842 

843def crypto_aead_aes256gcm_encrypt( 

844 message: bytes, aad: bytes | None, nonce: bytes, key: bytes 

845) -> bytes: 

846 """ 

847 Encrypt the given ``message`` using the AES-256-GCM 

848 construction. Requires the Intel AES-NI extensions, 

849 or the ARM Crypto extensions. 

850 

851 :param message: 

852 :type message: bytes 

853 :param aad: 

854 :type aad: Optional[bytes] 

855 :param nonce: 

856 :type nonce: bytes 

857 :param key: 

858 :type key: bytes 

859 :return: authenticated ciphertext 

860 :rtype: bytes 

861 """ 

862 ensure( 

863 lib.crypto_aead_aes256gcm_is_available() == 1, 

864 "Construction requires hardware acceleration", 

865 raising=exc.UnavailableError, 

866 ) 

867 

868 ensure( 

869 isinstance(message, bytes), 

870 "Input message type must be bytes", 

871 raising=exc.TypeError, 

872 ) 

873 

874 mlen = len(message) 

875 

876 ensure( 

877 mlen <= crypto_aead_aes256gcm_MESSAGEBYTES_MAX, 

878 f"Message must be at most {crypto_aead_aes256gcm_MESSAGEBYTES_MAX} bytes long", 

879 raising=exc.ValueError, 

880 ) 

881 

882 ensure( 

883 isinstance(aad, bytes) or (aad is None), 

884 "Additional data must be bytes or None", 

885 raising=exc.TypeError, 

886 ) 

887 

888 ensure( 

889 isinstance(nonce, bytes) 

890 and len(nonce) == crypto_aead_aes256gcm_NPUBBYTES, 

891 f"Nonce must be a {crypto_aead_aes256gcm_NPUBBYTES} bytes long bytes sequence", 

892 raising=exc.TypeError, 

893 ) 

894 

895 ensure( 

896 isinstance(key, bytes) and len(key) == crypto_aead_aes256gcm_KEYBYTES, 

897 f"Key must be a {crypto_aead_aes256gcm_KEYBYTES} bytes long bytes sequence", 

898 raising=exc.TypeError, 

899 ) 

900 

901 if aad: 

902 _aad = aad 

903 aalen = len(aad) 

904 else: 

905 _aad = ffi.NULL 

906 aalen = 0 

907 

908 mxout = mlen + crypto_aead_aes256gcm_ABYTES 

909 

910 clen = ffi.new("unsigned long long *") 

911 

912 ciphertext = ffi.new("unsigned char[]", mxout) 

913 

914 res = lib.crypto_aead_aes256gcm_encrypt( 

915 ciphertext, clen, message, mlen, _aad, aalen, ffi.NULL, nonce, key 

916 ) 

917 

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

919 return ffi.buffer(ciphertext, clen[0])[:] 

920 

921 

922def crypto_aead_aes256gcm_decrypt( 

923 ciphertext: bytes, aad: bytes | None, nonce: bytes, key: bytes 

924) -> bytes: 

925 """ 

926 Decrypt the given ``ciphertext`` using the AES-256-GCM 

927 construction. Requires the Intel AES-NI extensions, 

928 or the ARM Crypto extensions. 

929 

930 :param ciphertext: authenticated ciphertext 

931 :type ciphertext: bytes 

932 :param aad: 

933 :type aad: Optional[bytes] 

934 :param nonce: 

935 :type nonce: bytes 

936 :param key: 

937 :type key: bytes 

938 :return: message 

939 :rtype: bytes 

940 """ 

941 ensure( 

942 lib.crypto_aead_aes256gcm_is_available() == 1, 

943 "Construction requires hardware acceleration", 

944 raising=exc.UnavailableError, 

945 ) 

946 

947 ensure( 

948 isinstance(ciphertext, bytes), 

949 "Input ciphertext type must be bytes", 

950 raising=exc.TypeError, 

951 ) 

952 

953 clen = len(ciphertext) 

954 

955 ensure( 

956 clen <= _aead_aegis256_CRYPTBYTES_MAX, 

957 f"Ciphertext must be at most {_aead_aegis256_CRYPTBYTES_MAX} bytes long", 

958 raising=exc.ValueError, 

959 ) 

960 

961 ensure( 

962 isinstance(aad, bytes) or (aad is None), 

963 "Additional data must be bytes or None", 

964 raising=exc.TypeError, 

965 ) 

966 

967 ensure( 

968 isinstance(nonce, bytes) 

969 and len(nonce) == crypto_aead_aes256gcm_NPUBBYTES, 

970 f"Nonce must be a {crypto_aead_aes256gcm_NPUBBYTES} bytes long bytes sequence", 

971 raising=exc.TypeError, 

972 ) 

973 

974 ensure( 

975 isinstance(key, bytes) and len(key) == crypto_aead_aes256gcm_KEYBYTES, 

976 f"Key must be a {crypto_aead_aes256gcm_KEYBYTES} bytes long bytes sequence", 

977 raising=exc.TypeError, 

978 ) 

979 

980 mxout = clen - crypto_aead_aes256gcm_ABYTES 

981 mlen = ffi.new("unsigned long long *") 

982 message = ffi.new("unsigned char[]", mxout) 

983 

984 if aad: 

985 _aad = aad 

986 aalen = len(aad) 

987 else: 

988 _aad = ffi.NULL 

989 aalen = 0 

990 

991 res = lib.crypto_aead_aes256gcm_decrypt( 

992 message, mlen, ffi.NULL, ciphertext, clen, _aad, aalen, nonce, key 

993 ) 

994 

995 ensure(res == 0, "Decryption failed.", raising=exc.CryptoError) 

996 

997 return ffi.buffer(message, mlen[0])[:]