| @@ 268-308 (lines=41) @@ | ||
| 265 | * @param string $key |
|
| 266 | * @return string |
|
| 267 | */ |
|
| 268 | public static function aead_chacha20poly1305_ietf_encrypt( |
|
| 269 | $message = '', |
|
| 270 | $ad = '', |
|
| 271 | $nonce = '', |
|
| 272 | $key = '' |
|
| 273 | ) { |
|
| 274 | /** @var int $len - Length of the plaintext message */ |
|
| 275 | $len = ParagonIE_Sodium_Core_Util::strlen($message); |
|
| 276 | ||
| 277 | /** @var int $adlen - Length of the associated data */ |
|
| 278 | $adlen = ParagonIE_Sodium_Core_Util::strlen($ad); |
|
| 279 | ||
| 280 | /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ |
|
| 281 | $block0 = ParagonIE_Sodium_Core_ChaCha20::ietfStream( |
|
| 282 | 32, |
|
| 283 | $nonce, |
|
| 284 | $key |
|
| 285 | ); |
|
| 286 | $state = new ParagonIE_Sodium_Core_Poly1305_State($block0); |
|
| 287 | try { |
|
| 288 | ParagonIE_Sodium_Compat::memzero($block0); |
|
| 289 | } catch (Error $ex) { |
|
| 290 | $block0 = null; |
|
| 291 | } |
|
| 292 | ||
| 293 | /** @var string $ciphertext - Raw encrypted data */ |
|
| 294 | $ciphertext = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( |
|
| 295 | $message, |
|
| 296 | $nonce, |
|
| 297 | $key, |
|
| 298 | ParagonIE_Sodium_Core_Util::store64_le(1) |
|
| 299 | ); |
|
| 300 | ||
| 301 | $state->update($ad); |
|
| 302 | $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); |
|
| 303 | $state->update($ciphertext); |
|
| 304 | $state->update(str_repeat("\x00", ((0x10 - $len) & 0xf))); |
|
| 305 | $state->update(ParagonIE_Sodium_Core_Util::store64_le($adlen)); |
|
| 306 | $state->update(ParagonIE_Sodium_Core_Util::store64_le($len)); |
|
| 307 | return $ciphertext . $state->finish(); |
|
| 308 | } |
|
| 309 | ||
| 310 | /** |
|
| 311 | * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) |
|
| @@ 268-308 (lines=41) @@ | ||
| 265 | * @param string $key |
|
| 266 | * @return string |
|
| 267 | */ |
|
| 268 | public static function aead_chacha20poly1305_ietf_encrypt( |
|
| 269 | $message = '', |
|
| 270 | $ad = '', |
|
| 271 | $nonce = '', |
|
| 272 | $key = '' |
|
| 273 | ) { |
|
| 274 | /** @var int $len - Length of the plaintext message */ |
|
| 275 | $len = ParagonIE_Sodium_Core32_Util::strlen($message); |
|
| 276 | ||
| 277 | /** @var int $adlen - Length of the associated data */ |
|
| 278 | $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad); |
|
| 279 | ||
| 280 | /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ |
|
| 281 | $block0 = ParagonIE_Sodium_Core32_ChaCha20::ietfStream( |
|
| 282 | 32, |
|
| 283 | $nonce, |
|
| 284 | $key |
|
| 285 | ); |
|
| 286 | $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0); |
|
| 287 | try { |
|
| 288 | ParagonIE_Sodium_Compat::memzero($block0); |
|
| 289 | } catch (Error $ex) { |
|
| 290 | $block0 = null; |
|
| 291 | } |
|
| 292 | ||
| 293 | /** @var string $ciphertext - Raw encrypted data */ |
|
| 294 | $ciphertext = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( |
|
| 295 | $message, |
|
| 296 | $nonce, |
|
| 297 | $key, |
|
| 298 | ParagonIE_Sodium_Core32_Util::store64_le(1) |
|
| 299 | ); |
|
| 300 | ||
| 301 | $state->update($ad); |
|
| 302 | $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); |
|
| 303 | $state->update($ciphertext); |
|
| 304 | $state->update(str_repeat("\x00", ((0x10 - $len) & 0xf))); |
|
| 305 | $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen)); |
|
| 306 | $state->update(ParagonIE_Sodium_Core32_Util::store64_le($len)); |
|
| 307 | return $ciphertext . $state->finish(); |
|
| 308 | } |
|
| 309 | ||
| 310 | /** |
|
| 311 | * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) |
|