Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/PyNaCl-1.6.0.dev1-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 typing import Optional 

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: Optional[bytes], 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 "Message must be at most {} bytes long".format( 

149 crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX 

150 ), 

151 raising=exc.ValueError, 

152 ) 

153 

154 ensure( 

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

156 "Additional data must be bytes or None", 

157 raising=exc.TypeError, 

158 ) 

159 

160 ensure( 

161 isinstance(nonce, bytes) 

162 and len(nonce) == crypto_aead_chacha20poly1305_ietf_NPUBBYTES, 

163 "Nonce must be a {} bytes long bytes sequence".format( 

164 crypto_aead_chacha20poly1305_ietf_NPUBBYTES 

165 ), 

166 raising=exc.TypeError, 

167 ) 

168 

169 ensure( 

170 isinstance(key, bytes) 

171 and len(key) == crypto_aead_chacha20poly1305_ietf_KEYBYTES, 

172 "Key must be a {} bytes long bytes sequence".format( 

173 crypto_aead_chacha20poly1305_ietf_KEYBYTES 

174 ), 

175 raising=exc.TypeError, 

176 ) 

177 

178 if aad: 

179 _aad = aad 

180 aalen = len(aad) 

181 else: 

182 _aad = ffi.NULL 

183 aalen = 0 

184 

185 mxout = mlen + crypto_aead_chacha20poly1305_ietf_ABYTES 

186 

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

188 

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

190 

191 res = lib.crypto_aead_chacha20poly1305_ietf_encrypt( 

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

193 ) 

194 

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

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

197 

198 

199def crypto_aead_chacha20poly1305_ietf_decrypt( 

200 ciphertext: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

201) -> bytes: 

202 """ 

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

204 construction described in RFC7539. 

205 

206 :param ciphertext: 

207 :type ciphertext: bytes 

208 :param aad: 

209 :type aad: Optional[bytes] 

210 :param nonce: 

211 :type nonce: bytes 

212 :param key: 

213 :type key: bytes 

214 :return: message 

215 :rtype: bytes 

216 """ 

217 ensure( 

218 isinstance(ciphertext, bytes), 

219 "Input ciphertext type must be bytes", 

220 raising=exc.TypeError, 

221 ) 

222 

223 clen = len(ciphertext) 

224 

225 ensure( 

226 clen <= _aead_chacha20poly1305_ietf_CRYPTBYTES_MAX, 

227 "Ciphertext must be at most {} bytes long".format( 

228 _aead_chacha20poly1305_ietf_CRYPTBYTES_MAX 

229 ), 

230 raising=exc.ValueError, 

231 ) 

232 

233 ensure( 

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

235 "Additional data must be bytes or None", 

236 raising=exc.TypeError, 

237 ) 

238 

239 ensure( 

240 isinstance(nonce, bytes) 

241 and len(nonce) == crypto_aead_chacha20poly1305_ietf_NPUBBYTES, 

242 "Nonce must be a {} bytes long bytes sequence".format( 

243 crypto_aead_chacha20poly1305_ietf_NPUBBYTES 

244 ), 

245 raising=exc.TypeError, 

246 ) 

247 

248 ensure( 

249 isinstance(key, bytes) 

250 and len(key) == crypto_aead_chacha20poly1305_ietf_KEYBYTES, 

251 "Key must be a {} bytes long bytes sequence".format( 

252 crypto_aead_chacha20poly1305_ietf_KEYBYTES 

253 ), 

254 raising=exc.TypeError, 

255 ) 

256 

257 mxout = clen - crypto_aead_chacha20poly1305_ietf_ABYTES 

258 

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

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

261 

262 if aad: 

263 _aad = aad 

264 aalen = len(aad) 

265 else: 

266 _aad = ffi.NULL 

267 aalen = 0 

268 

269 res = lib.crypto_aead_chacha20poly1305_ietf_decrypt( 

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

271 ) 

272 

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

274 

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

276 

277 

278def crypto_aead_chacha20poly1305_encrypt( 

279 message: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

280) -> bytes: 

281 """ 

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

283 described in draft-agl-tls-chacha20poly1305. 

284 

285 :param message: 

286 :type message: bytes 

287 :param aad: 

288 :type aad: Optional[bytes] 

289 :param nonce: 

290 :type nonce: bytes 

291 :param key: 

292 :type key: bytes 

293 :return: authenticated ciphertext 

294 :rtype: bytes 

295 """ 

296 ensure( 

297 isinstance(message, bytes), 

298 "Input message type must be bytes", 

299 raising=exc.TypeError, 

300 ) 

301 

302 mlen = len(message) 

303 

304 ensure( 

305 mlen <= crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX, 

306 "Message must be at most {} bytes long".format( 

307 crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX 

308 ), 

309 raising=exc.ValueError, 

310 ) 

311 

312 ensure( 

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

314 "Additional data must be bytes or None", 

315 raising=exc.TypeError, 

316 ) 

317 

318 ensure( 

319 isinstance(nonce, bytes) 

320 and len(nonce) == crypto_aead_chacha20poly1305_NPUBBYTES, 

321 "Nonce must be a {} bytes long bytes sequence".format( 

322 crypto_aead_chacha20poly1305_NPUBBYTES 

323 ), 

324 raising=exc.TypeError, 

325 ) 

326 

327 ensure( 

328 isinstance(key, bytes) 

329 and len(key) == crypto_aead_chacha20poly1305_KEYBYTES, 

330 "Key must be a {} bytes long bytes sequence".format( 

331 crypto_aead_chacha20poly1305_KEYBYTES 

332 ), 

333 raising=exc.TypeError, 

334 ) 

335 

336 if aad: 

337 _aad = aad 

338 aalen = len(aad) 

339 else: 

340 _aad = ffi.NULL 

341 aalen = 0 

342 

343 mxout = mlen + crypto_aead_chacha20poly1305_ietf_ABYTES 

344 

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

346 

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

348 

349 res = lib.crypto_aead_chacha20poly1305_encrypt( 

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

351 ) 

352 

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

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

355 

356 

357def crypto_aead_chacha20poly1305_decrypt( 

358 ciphertext: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

359) -> bytes: 

360 """ 

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

362 described in draft-agl-tls-chacha20poly1305. 

363 

364 :param ciphertext: authenticated ciphertext 

365 :type ciphertext: bytes 

366 :param aad: 

367 :type aad: Optional[bytes] 

368 :param nonce: 

369 :type nonce: bytes 

370 :param key: 

371 :type key: bytes 

372 :return: message 

373 :rtype: bytes 

374 """ 

375 ensure( 

376 isinstance(ciphertext, bytes), 

377 "Input ciphertext type must be bytes", 

378 raising=exc.TypeError, 

379 ) 

380 

381 clen = len(ciphertext) 

382 

383 ensure( 

384 clen <= _aead_chacha20poly1305_CRYPTBYTES_MAX, 

385 "Ciphertext must be at most {} bytes long".format( 

386 _aead_chacha20poly1305_CRYPTBYTES_MAX 

387 ), 

388 raising=exc.ValueError, 

389 ) 

390 

391 ensure( 

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

393 "Additional data must be bytes or None", 

394 raising=exc.TypeError, 

395 ) 

396 

397 ensure( 

398 isinstance(nonce, bytes) 

399 and len(nonce) == crypto_aead_chacha20poly1305_NPUBBYTES, 

400 "Nonce must be a {} bytes long bytes sequence".format( 

401 crypto_aead_chacha20poly1305_NPUBBYTES 

402 ), 

403 raising=exc.TypeError, 

404 ) 

405 

406 ensure( 

407 isinstance(key, bytes) 

408 and len(key) == crypto_aead_chacha20poly1305_KEYBYTES, 

409 "Key must be a {} bytes long bytes sequence".format( 

410 crypto_aead_chacha20poly1305_KEYBYTES 

411 ), 

412 raising=exc.TypeError, 

413 ) 

414 

415 mxout = clen - crypto_aead_chacha20poly1305_ABYTES 

416 

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

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

419 

420 if aad: 

421 _aad = aad 

422 aalen = len(aad) 

423 else: 

424 _aad = ffi.NULL 

425 aalen = 0 

426 

427 res = lib.crypto_aead_chacha20poly1305_decrypt( 

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

429 ) 

430 

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

432 

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

434 

435 

436def crypto_aead_xchacha20poly1305_ietf_encrypt( 

437 message: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

438) -> bytes: 

439 """ 

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

441 construction. 

442 

443 :param message: 

444 :type message: bytes 

445 :param aad: 

446 :type aad: Optional[bytes] 

447 :param nonce: 

448 :type nonce: bytes 

449 :param key: 

450 :type key: bytes 

451 :return: authenticated ciphertext 

452 :rtype: bytes 

453 """ 

454 ensure( 

455 isinstance(message, bytes), 

456 "Input message type must be bytes", 

457 raising=exc.TypeError, 

458 ) 

459 

460 mlen = len(message) 

461 

462 ensure( 

463 mlen <= crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX, 

464 "Message must be at most {} bytes long".format( 

465 crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX 

466 ), 

467 raising=exc.ValueError, 

468 ) 

469 

470 ensure( 

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

472 "Additional data must be bytes or None", 

473 raising=exc.TypeError, 

474 ) 

475 

476 ensure( 

477 isinstance(nonce, bytes) 

478 and len(nonce) == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES, 

479 "Nonce must be a {} bytes long bytes sequence".format( 

480 crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 

481 ), 

482 raising=exc.TypeError, 

483 ) 

484 

485 ensure( 

486 isinstance(key, bytes) 

487 and len(key) == crypto_aead_xchacha20poly1305_ietf_KEYBYTES, 

488 "Key must be a {} bytes long bytes sequence".format( 

489 crypto_aead_xchacha20poly1305_ietf_KEYBYTES 

490 ), 

491 raising=exc.TypeError, 

492 ) 

493 

494 if aad: 

495 _aad = aad 

496 aalen = len(aad) 

497 else: 

498 _aad = ffi.NULL 

499 aalen = 0 

500 

501 mxout = mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES 

502 

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

504 

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

506 

507 res = lib.crypto_aead_xchacha20poly1305_ietf_encrypt( 

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

509 ) 

510 

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

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

513 

514 

515def crypto_aead_xchacha20poly1305_ietf_decrypt( 

516 ciphertext: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

517) -> bytes: 

518 """ 

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

520 construction. 

521 

522 :param ciphertext: authenticated ciphertext 

523 :type ciphertext: bytes 

524 :param aad: 

525 :type aad: Optional[bytes] 

526 :param nonce: 

527 :type nonce: bytes 

528 :param key: 

529 :type key: bytes 

530 :return: message 

531 :rtype: bytes 

532 """ 

533 ensure( 

534 isinstance(ciphertext, bytes), 

535 "Input ciphertext type must be bytes", 

536 raising=exc.TypeError, 

537 ) 

538 

539 clen = len(ciphertext) 

540 

541 ensure( 

542 clen <= _aead_xchacha20poly1305_ietf_CRYPTBYTES_MAX, 

543 "Ciphertext must be at most {} bytes long".format( 

544 _aead_xchacha20poly1305_ietf_CRYPTBYTES_MAX 

545 ), 

546 raising=exc.ValueError, 

547 ) 

548 

549 ensure( 

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

551 "Additional data must be bytes or None", 

552 raising=exc.TypeError, 

553 ) 

554 

555 ensure( 

556 isinstance(nonce, bytes) 

557 and len(nonce) == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES, 

558 "Nonce must be a {} bytes long bytes sequence".format( 

559 crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 

560 ), 

561 raising=exc.TypeError, 

562 ) 

563 

564 ensure( 

565 isinstance(key, bytes) 

566 and len(key) == crypto_aead_xchacha20poly1305_ietf_KEYBYTES, 

567 "Key must be a {} bytes long bytes sequence".format( 

568 crypto_aead_xchacha20poly1305_ietf_KEYBYTES 

569 ), 

570 raising=exc.TypeError, 

571 ) 

572 

573 mxout = clen - crypto_aead_xchacha20poly1305_ietf_ABYTES 

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

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

576 

577 if aad: 

578 _aad = aad 

579 aalen = len(aad) 

580 else: 

581 _aad = ffi.NULL 

582 aalen = 0 

583 

584 res = lib.crypto_aead_xchacha20poly1305_ietf_decrypt( 

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

586 ) 

587 

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

589 

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

591 

592 

593def crypto_aead_aegis256_encrypt( 

594 message: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

595) -> bytes: 

596 """ 

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

598 construction. 

599 

600 :param message: 

601 :type message: bytes 

602 :param aad: 

603 :type aad: Optional[bytes] 

604 :param nonce: 

605 :type nonce: bytes 

606 :param key: 

607 :type key: bytes 

608 :return: authenticated ciphertext 

609 :rtype: bytes 

610 """ 

611 ensure( 

612 isinstance(message, bytes), 

613 "Input message type must be bytes", 

614 raising=exc.TypeError, 

615 ) 

616 

617 mlen = len(message) 

618 

619 ensure( 

620 mlen <= crypto_aead_aegis256_MESSAGEBYTES_MAX, 

621 "Message must be at most {} bytes long".format( 

622 crypto_aead_aegis256_MESSAGEBYTES_MAX 

623 ), 

624 raising=exc.ValueError, 

625 ) 

626 

627 ensure( 

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

629 "Additional data must be bytes or None", 

630 raising=exc.TypeError, 

631 ) 

632 

633 ensure( 

634 isinstance(nonce, bytes) 

635 and len(nonce) == crypto_aead_aegis256_NPUBBYTES, 

636 "Nonce must be a {} bytes long bytes sequence".format( 

637 crypto_aead_aegis256_NPUBBYTES 

638 ), 

639 raising=exc.TypeError, 

640 ) 

641 

642 ensure( 

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

644 "Key must be a {} bytes long bytes sequence".format( 

645 crypto_aead_aegis256_KEYBYTES 

646 ), 

647 raising=exc.TypeError, 

648 ) 

649 

650 if aad: 

651 _aad = aad 

652 aalen = len(aad) 

653 else: 

654 _aad = ffi.NULL 

655 aalen = 0 

656 

657 mxout = mlen + crypto_aead_aegis256_ABYTES 

658 

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

660 

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

662 

663 res = lib.crypto_aead_aegis256_encrypt( 

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

665 ) 

666 

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

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

669 

670 

671def crypto_aead_aegis256_decrypt( 

672 ciphertext: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

673) -> bytes: 

674 """ 

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

676 construction. 

677 

678 :param ciphertext: authenticated ciphertext 

679 :type ciphertext: bytes 

680 :param aad: 

681 :type aad: Optional[bytes] 

682 :param nonce: 

683 :type nonce: bytes 

684 :param key: 

685 :type key: bytes 

686 :return: message 

687 :rtype: bytes 

688 """ 

689 ensure( 

690 isinstance(ciphertext, bytes), 

691 "Input ciphertext type must be bytes", 

692 raising=exc.TypeError, 

693 ) 

694 

695 clen = len(ciphertext) 

696 

697 ensure( 

698 clen <= _aead_aegis256_CRYPTBYTES_MAX, 

699 "Ciphertext must be at most {} bytes long".format( 

700 _aead_aegis256_CRYPTBYTES_MAX 

701 ), 

702 raising=exc.ValueError, 

703 ) 

704 

705 ensure( 

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

707 "Additional data must be bytes or None", 

708 raising=exc.TypeError, 

709 ) 

710 

711 ensure( 

712 isinstance(nonce, bytes) 

713 and len(nonce) == crypto_aead_aegis256_NPUBBYTES, 

714 "Nonce must be a {} bytes long bytes sequence".format( 

715 crypto_aead_aegis256_NPUBBYTES 

716 ), 

717 raising=exc.TypeError, 

718 ) 

719 

720 ensure( 

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

722 "Key must be a {} bytes long bytes sequence".format( 

723 crypto_aead_aegis256_KEYBYTES 

724 ), 

725 raising=exc.TypeError, 

726 ) 

727 

728 mxout = clen - crypto_aead_aegis256_ABYTES 

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

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

731 

732 if aad: 

733 _aad = aad 

734 aalen = len(aad) 

735 else: 

736 _aad = ffi.NULL 

737 aalen = 0 

738 

739 res = lib.crypto_aead_aegis256_decrypt( 

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

741 ) 

742 

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

744 

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

746 

747 

748def crypto_aead_aegis128l_encrypt( 

749 message: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

750) -> bytes: 

751 """ 

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

753 construction. 

754 

755 :param message: 

756 :type message: bytes 

757 :param aad: 

758 :type aad: Optional[bytes] 

759 :param nonce: 

760 :type nonce: bytes 

761 :param key: 

762 :type key: bytes 

763 :return: authenticated ciphertext 

764 :rtype: bytes 

765 """ 

766 ensure( 

767 isinstance(message, bytes), 

768 "Input message type must be bytes", 

769 raising=exc.TypeError, 

770 ) 

771 

772 mlen = len(message) 

773 

774 ensure( 

775 mlen <= crypto_aead_aegis128l_MESSAGEBYTES_MAX, 

776 "Message must be at most {} bytes long".format( 

777 crypto_aead_aegis128l_MESSAGEBYTES_MAX 

778 ), 

779 raising=exc.ValueError, 

780 ) 

781 

782 ensure( 

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

784 "Additional data must be bytes or None", 

785 raising=exc.TypeError, 

786 ) 

787 

788 ensure( 

789 isinstance(nonce, bytes) 

790 and len(nonce) == crypto_aead_aegis128l_NPUBBYTES, 

791 "Nonce must be a {} bytes long bytes sequence".format( 

792 crypto_aead_aegis128l_NPUBBYTES 

793 ), 

794 raising=exc.TypeError, 

795 ) 

796 

797 ensure( 

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

799 "Key must be a {} bytes long bytes sequence".format( 

800 crypto_aead_aegis128l_KEYBYTES 

801 ), 

802 raising=exc.TypeError, 

803 ) 

804 

805 if aad: 

806 _aad = aad 

807 aalen = len(aad) 

808 else: 

809 _aad = ffi.NULL 

810 aalen = 0 

811 

812 mxout = mlen + crypto_aead_aegis128l_ABYTES 

813 

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

815 

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

817 

818 res = lib.crypto_aead_aegis128l_encrypt( 

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

820 ) 

821 

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

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

824 

825 

826def crypto_aead_aegis128l_decrypt( 

827 ciphertext: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

828) -> bytes: 

829 """ 

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

831 construction. 

832 

833 :param ciphertext: authenticated ciphertext 

834 :type ciphertext: bytes 

835 :param aad: 

836 :type aad: Optional[bytes] 

837 :param nonce: 

838 :type nonce: bytes 

839 :param key: 

840 :type key: bytes 

841 :return: message 

842 :rtype: bytes 

843 """ 

844 ensure( 

845 isinstance(ciphertext, bytes), 

846 "Input ciphertext type must be bytes", 

847 raising=exc.TypeError, 

848 ) 

849 

850 clen = len(ciphertext) 

851 

852 ensure( 

853 clen <= _aead_aegis256_CRYPTBYTES_MAX, 

854 "Ciphertext must be at most {} bytes long".format( 

855 _aead_aegis256_CRYPTBYTES_MAX 

856 ), 

857 raising=exc.ValueError, 

858 ) 

859 

860 ensure( 

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

862 "Additional data must be bytes or None", 

863 raising=exc.TypeError, 

864 ) 

865 

866 ensure( 

867 isinstance(nonce, bytes) 

868 and len(nonce) == crypto_aead_aegis128l_NPUBBYTES, 

869 "Nonce must be a {} bytes long bytes sequence".format( 

870 crypto_aead_aegis128l_NPUBBYTES 

871 ), 

872 raising=exc.TypeError, 

873 ) 

874 

875 ensure( 

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

877 "Key must be a {} bytes long bytes sequence".format( 

878 crypto_aead_aegis128l_KEYBYTES 

879 ), 

880 raising=exc.TypeError, 

881 ) 

882 

883 mxout = clen - crypto_aead_aegis128l_ABYTES 

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

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

886 

887 if aad: 

888 _aad = aad 

889 aalen = len(aad) 

890 else: 

891 _aad = ffi.NULL 

892 aalen = 0 

893 

894 res = lib.crypto_aead_aegis128l_decrypt( 

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

896 ) 

897 

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

899 

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

901 

902 

903def crypto_aead_aes256gcm_encrypt( 

904 message: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

905) -> bytes: 

906 """ 

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

908 construction. Requires the Intel AES-NI extensions, 

909 or the ARM Crypto extensions. 

910 

911 :param message: 

912 :type message: bytes 

913 :param aad: 

914 :type aad: Optional[bytes] 

915 :param nonce: 

916 :type nonce: bytes 

917 :param key: 

918 :type key: bytes 

919 :return: authenticated ciphertext 

920 :rtype: bytes 

921 """ 

922 ensure( 

923 lib.crypto_aead_aes256gcm_is_available() == 1, 

924 "Construction requires hardware acceleration", 

925 raising=exc.UnavailableError, 

926 ) 

927 

928 ensure( 

929 isinstance(message, bytes), 

930 "Input message type must be bytes", 

931 raising=exc.TypeError, 

932 ) 

933 

934 mlen = len(message) 

935 

936 ensure( 

937 mlen <= crypto_aead_aes256gcm_MESSAGEBYTES_MAX, 

938 "Message must be at most {} bytes long".format( 

939 crypto_aead_aes256gcm_MESSAGEBYTES_MAX 

940 ), 

941 raising=exc.ValueError, 

942 ) 

943 

944 ensure( 

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

946 "Additional data must be bytes or None", 

947 raising=exc.TypeError, 

948 ) 

949 

950 ensure( 

951 isinstance(nonce, bytes) 

952 and len(nonce) == crypto_aead_aes256gcm_NPUBBYTES, 

953 "Nonce must be a {} bytes long bytes sequence".format( 

954 crypto_aead_aes256gcm_NPUBBYTES 

955 ), 

956 raising=exc.TypeError, 

957 ) 

958 

959 ensure( 

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

961 "Key must be a {} bytes long bytes sequence".format( 

962 crypto_aead_aes256gcm_KEYBYTES 

963 ), 

964 raising=exc.TypeError, 

965 ) 

966 

967 if aad: 

968 _aad = aad 

969 aalen = len(aad) 

970 else: 

971 _aad = ffi.NULL 

972 aalen = 0 

973 

974 mxout = mlen + crypto_aead_aes256gcm_ABYTES 

975 

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

977 

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

979 

980 res = lib.crypto_aead_aes256gcm_encrypt( 

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

982 ) 

983 

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

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

986 

987 

988def crypto_aead_aes256gcm_decrypt( 

989 ciphertext: bytes, aad: Optional[bytes], nonce: bytes, key: bytes 

990) -> bytes: 

991 """ 

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

993 construction. Requires the Intel AES-NI extensions, 

994 or the ARM Crypto extensions. 

995 

996 :param ciphertext: authenticated ciphertext 

997 :type ciphertext: bytes 

998 :param aad: 

999 :type aad: Optional[bytes] 

1000 :param nonce: 

1001 :type nonce: bytes 

1002 :param key: 

1003 :type key: bytes 

1004 :return: message 

1005 :rtype: bytes 

1006 """ 

1007 ensure( 

1008 lib.crypto_aead_aes256gcm_is_available() == 1, 

1009 "Construction requires hardware acceleration", 

1010 raising=exc.UnavailableError, 

1011 ) 

1012 

1013 ensure( 

1014 isinstance(ciphertext, bytes), 

1015 "Input ciphertext type must be bytes", 

1016 raising=exc.TypeError, 

1017 ) 

1018 

1019 clen = len(ciphertext) 

1020 

1021 ensure( 

1022 clen <= _aead_aegis256_CRYPTBYTES_MAX, 

1023 "Ciphertext must be at most {} bytes long".format( 

1024 _aead_aegis256_CRYPTBYTES_MAX 

1025 ), 

1026 raising=exc.ValueError, 

1027 ) 

1028 

1029 ensure( 

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

1031 "Additional data must be bytes or None", 

1032 raising=exc.TypeError, 

1033 ) 

1034 

1035 ensure( 

1036 isinstance(nonce, bytes) 

1037 and len(nonce) == crypto_aead_aes256gcm_NPUBBYTES, 

1038 "Nonce must be a {} bytes long bytes sequence".format( 

1039 crypto_aead_aes256gcm_NPUBBYTES 

1040 ), 

1041 raising=exc.TypeError, 

1042 ) 

1043 

1044 ensure( 

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

1046 "Key must be a {} bytes long bytes sequence".format( 

1047 crypto_aead_aes256gcm_KEYBYTES 

1048 ), 

1049 raising=exc.TypeError, 

1050 ) 

1051 

1052 mxout = clen - crypto_aead_aes256gcm_ABYTES 

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

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

1055 

1056 if aad: 

1057 _aad = aad 

1058 aalen = len(aad) 

1059 else: 

1060 _aad = ffi.NULL 

1061 aalen = 0 

1062 

1063 res = lib.crypto_aead_aes256gcm_decrypt( 

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

1065 ) 

1066 

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

1068 

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