| @@ 921-980 (lines=60) @@ | ||
| 918 | * @return string |
|
| 919 | * @throws Error |
|
| 920 | */ |
|
| 921 | public static function secretbox_open($ciphertext, $nonce, $key) |
|
| 922 | { |
|
| 923 | /** @var string $mac */ |
|
| 924 | $mac = ParagonIE_Sodium_Core_Util::substr( |
|
| 925 | $ciphertext, |
|
| 926 | 0, |
|
| 927 | self::secretbox_xsalsa20poly1305_MACBYTES |
|
| 928 | ); |
|
| 929 | ||
| 930 | /** @var string $c */ |
|
| 931 | $c = ParagonIE_Sodium_Core_Util::substr( |
|
| 932 | $ciphertext, |
|
| 933 | self::secretbox_xsalsa20poly1305_MACBYTES |
|
| 934 | ); |
|
| 935 | ||
| 936 | /** @var int $clen */ |
|
| 937 | $clen = ParagonIE_Sodium_Core_Util::strlen($c); |
|
| 938 | ||
| 939 | /** @var string $subkey */ |
|
| 940 | $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key); |
|
| 941 | ||
| 942 | /** @var string $block0 */ |
|
| 943 | $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20( |
|
| 944 | 64, |
|
| 945 | ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), |
|
| 946 | $subkey |
|
| 947 | ); |
|
| 948 | $verified = ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify( |
|
| 949 | $mac, |
|
| 950 | $c, |
|
| 951 | ParagonIE_Sodium_Core_Util::substr($block0, 0, 32) |
|
| 952 | ); |
|
| 953 | if (!$verified) { |
|
| 954 | try { |
|
| 955 | ParagonIE_Sodium_Compat::memzero($subkey); |
|
| 956 | } catch (Error $ex) { |
|
| 957 | $subkey = null; |
|
| 958 | } |
|
| 959 | throw new Error('Invalid MAC'); |
|
| 960 | } |
|
| 961 | ||
| 962 | /** @var string $m - Decrypted message */ |
|
| 963 | $m = ParagonIE_Sodium_Core_Util::xorStrings( |
|
| 964 | ParagonIE_Sodium_Core_Util::substr($block0, self::secretbox_xsalsa20poly1305_ZEROBYTES), |
|
| 965 | ParagonIE_Sodium_Core_Util::substr($c, 0, self::secretbox_xsalsa20poly1305_ZEROBYTES) |
|
| 966 | ); |
|
| 967 | if ($clen > self::secretbox_xsalsa20poly1305_ZEROBYTES) { |
|
| 968 | // We had more than 1 block, so let's continue to decrypt the rest. |
|
| 969 | $m .= ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic( |
|
| 970 | ParagonIE_Sodium_Core_Util::substr( |
|
| 971 | $c, |
|
| 972 | self::secretbox_xsalsa20poly1305_ZEROBYTES |
|
| 973 | ), |
|
| 974 | ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), |
|
| 975 | 1, |
|
| 976 | $subkey |
|
| 977 | ); |
|
| 978 | } |
|
| 979 | return $m; |
|
| 980 | } |
|
| 981 | ||
| 982 | /** |
|
| 983 | * XChaCha20-Poly1305 authenticated symmetric-key encryption. |
|
| @@ 1070-1131 (lines=62) @@ | ||
| 1067 | * @return string |
|
| 1068 | * @throws Error |
|
| 1069 | */ |
|
| 1070 | public static function secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key) |
|
| 1071 | { |
|
| 1072 | /** @var string $mac */ |
|
| 1073 | $mac = ParagonIE_Sodium_Core_Util::substr( |
|
| 1074 | $ciphertext, |
|
| 1075 | 0, |
|
| 1076 | self::secretbox_xchacha20poly1305_MACBYTES |
|
| 1077 | ); |
|
| 1078 | ||
| 1079 | /** @var string $c */ |
|
| 1080 | $c = ParagonIE_Sodium_Core_Util::substr( |
|
| 1081 | $ciphertext, |
|
| 1082 | self::secretbox_xchacha20poly1305_MACBYTES |
|
| 1083 | ); |
|
| 1084 | ||
| 1085 | /** @var int $clen */ |
|
| 1086 | $clen = ParagonIE_Sodium_Core_Util::strlen($c); |
|
| 1087 | ||
| 1088 | /** @var string $subkey */ |
|
| 1089 | $subkey = ParagonIE_Sodium_Core_HChaCha20::hchacha20($nonce, $key); |
|
| 1090 | ||
| 1091 | /** @var string $block0 */ |
|
| 1092 | $block0 = ParagonIE_Sodium_Core_ChaCha20::stream( |
|
| 1093 | 64, |
|
| 1094 | ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), |
|
| 1095 | $subkey |
|
| 1096 | ); |
|
| 1097 | $verified = ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify( |
|
| 1098 | $mac, |
|
| 1099 | $c, |
|
| 1100 | ParagonIE_Sodium_Core_Util::substr($block0, 0, 32) |
|
| 1101 | ); |
|
| 1102 | ||
| 1103 | if (!$verified) { |
|
| 1104 | try { |
|
| 1105 | ParagonIE_Sodium_Compat::memzero($subkey); |
|
| 1106 | } catch (Error $ex) { |
|
| 1107 | $subkey = null; |
|
| 1108 | } |
|
| 1109 | throw new Error('Invalid MAC'); |
|
| 1110 | } |
|
| 1111 | ||
| 1112 | /** @var string $m - Decrypted message */ |
|
| 1113 | $m = ParagonIE_Sodium_Core_Util::xorStrings( |
|
| 1114 | ParagonIE_Sodium_Core_Util::substr($block0, self::secretbox_xchacha20poly1305_ZEROBYTES), |
|
| 1115 | ParagonIE_Sodium_Core_Util::substr($c, 0, self::secretbox_xchacha20poly1305_ZEROBYTES) |
|
| 1116 | ); |
|
| 1117 | ||
| 1118 | if ($clen > self::secretbox_xchacha20poly1305_ZEROBYTES) { |
|
| 1119 | // We had more than 1 block, so let's continue to decrypt the rest. |
|
| 1120 | $m .= ParagonIE_Sodium_Core_ChaCha20::streamXorIc( |
|
| 1121 | ParagonIE_Sodium_Core_Util::substr( |
|
| 1122 | $c, |
|
| 1123 | self::secretbox_xchacha20poly1305_ZEROBYTES |
|
| 1124 | ), |
|
| 1125 | ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), |
|
| 1126 | $subkey, |
|
| 1127 | ParagonIE_Sodium_Core_Util::store64_le(1) |
|
| 1128 | ); |
|
| 1129 | } |
|
| 1130 | return $m; |
|
| 1131 | } |
|
| 1132 | ||
| 1133 | /** |
|
| 1134 | * Detached Ed25519 signature. |
|
| @@ 906-965 (lines=60) @@ | ||
| 903 | * @return string |
|
| 904 | * @throws Error |
|
| 905 | */ |
|
| 906 | public static function secretbox_open($ciphertext, $nonce, $key) |
|
| 907 | { |
|
| 908 | /** @var string $mac */ |
|
| 909 | $mac = ParagonIE_Sodium_Core32_Util::substr( |
|
| 910 | $ciphertext, |
|
| 911 | 0, |
|
| 912 | self::secretbox_xsalsa20poly1305_MACBYTES |
|
| 913 | ); |
|
| 914 | ||
| 915 | /** @var string $c */ |
|
| 916 | $c = ParagonIE_Sodium_Core32_Util::substr( |
|
| 917 | $ciphertext, |
|
| 918 | self::secretbox_xsalsa20poly1305_MACBYTES |
|
| 919 | ); |
|
| 920 | ||
| 921 | /** @var int $clen */ |
|
| 922 | $clen = ParagonIE_Sodium_Core32_Util::strlen($c); |
|
| 923 | ||
| 924 | /** @var string $subkey */ |
|
| 925 | $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key); |
|
| 926 | ||
| 927 | /** @var string $block0 */ |
|
| 928 | $block0 = ParagonIE_Sodium_Core32_Salsa20::salsa20( |
|
| 929 | 64, |
|
| 930 | ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), |
|
| 931 | $subkey |
|
| 932 | ); |
|
| 933 | $verified = ParagonIE_Sodium_Core32_Poly1305::onetimeauth_verify( |
|
| 934 | $mac, |
|
| 935 | $c, |
|
| 936 | ParagonIE_Sodium_Core32_Util::substr($block0, 0, 32) |
|
| 937 | ); |
|
| 938 | if (!$verified) { |
|
| 939 | try { |
|
| 940 | ParagonIE_Sodium_Compat::memzero($subkey); |
|
| 941 | } catch (Error $ex) { |
|
| 942 | $subkey = null; |
|
| 943 | } |
|
| 944 | throw new Error('Invalid MAC'); |
|
| 945 | } |
|
| 946 | ||
| 947 | /** @var string $m - Decrypted message */ |
|
| 948 | $m = ParagonIE_Sodium_Core32_Util::xorStrings( |
|
| 949 | ParagonIE_Sodium_Core32_Util::substr($block0, self::secretbox_xsalsa20poly1305_ZEROBYTES), |
|
| 950 | ParagonIE_Sodium_Core32_Util::substr($c, 0, self::secretbox_xsalsa20poly1305_ZEROBYTES) |
|
| 951 | ); |
|
| 952 | if ($clen > self::secretbox_xsalsa20poly1305_ZEROBYTES) { |
|
| 953 | // We had more than 1 block, so let's continue to decrypt the rest. |
|
| 954 | $m .= ParagonIE_Sodium_Core32_Salsa20::salsa20_xor_ic( |
|
| 955 | ParagonIE_Sodium_Core32_Util::substr( |
|
| 956 | $c, |
|
| 957 | self::secretbox_xsalsa20poly1305_ZEROBYTES |
|
| 958 | ), |
|
| 959 | ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), |
|
| 960 | 1, |
|
| 961 | $subkey |
|
| 962 | ); |
|
| 963 | } |
|
| 964 | return $m; |
|
| 965 | } |
|
| 966 | ||
| 967 | /** |
|
| 968 | * XChaCha20-Poly1305 authenticated symmetric-key encryption. |
|
| @@ 1055-1116 (lines=62) @@ | ||
| 1052 | * @return string |
|
| 1053 | * @throws Error |
|
| 1054 | */ |
|
| 1055 | public static function secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key) |
|
| 1056 | { |
|
| 1057 | /** @var string $mac */ |
|
| 1058 | $mac = ParagonIE_Sodium_Core32_Util::substr( |
|
| 1059 | $ciphertext, |
|
| 1060 | 0, |
|
| 1061 | self::secretbox_xchacha20poly1305_MACBYTES |
|
| 1062 | ); |
|
| 1063 | ||
| 1064 | /** @var string $c */ |
|
| 1065 | $c = ParagonIE_Sodium_Core32_Util::substr( |
|
| 1066 | $ciphertext, |
|
| 1067 | self::secretbox_xchacha20poly1305_MACBYTES |
|
| 1068 | ); |
|
| 1069 | ||
| 1070 | /** @var int $clen */ |
|
| 1071 | $clen = ParagonIE_Sodium_Core32_Util::strlen($c); |
|
| 1072 | ||
| 1073 | /** @var string $subkey */ |
|
| 1074 | $subkey = ParagonIE_Sodium_Core32_HChaCha20::hchacha20($nonce, $key); |
|
| 1075 | ||
| 1076 | /** @var string $block0 */ |
|
| 1077 | $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream( |
|
| 1078 | 64, |
|
| 1079 | ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), |
|
| 1080 | $subkey |
|
| 1081 | ); |
|
| 1082 | $verified = ParagonIE_Sodium_Core32_Poly1305::onetimeauth_verify( |
|
| 1083 | $mac, |
|
| 1084 | $c, |
|
| 1085 | ParagonIE_Sodium_Core32_Util::substr($block0, 0, 32) |
|
| 1086 | ); |
|
| 1087 | ||
| 1088 | if (!$verified) { |
|
| 1089 | try { |
|
| 1090 | ParagonIE_Sodium_Compat::memzero($subkey); |
|
| 1091 | } catch (Error $ex) { |
|
| 1092 | $subkey = null; |
|
| 1093 | } |
|
| 1094 | throw new Error('Invalid MAC'); |
|
| 1095 | } |
|
| 1096 | ||
| 1097 | /** @var string $m - Decrypted message */ |
|
| 1098 | $m = ParagonIE_Sodium_Core32_Util::xorStrings( |
|
| 1099 | ParagonIE_Sodium_Core32_Util::substr($block0, self::secretbox_xchacha20poly1305_ZEROBYTES), |
|
| 1100 | ParagonIE_Sodium_Core32_Util::substr($c, 0, self::secretbox_xchacha20poly1305_ZEROBYTES) |
|
| 1101 | ); |
|
| 1102 | ||
| 1103 | if ($clen > self::secretbox_xchacha20poly1305_ZEROBYTES) { |
|
| 1104 | // We had more than 1 block, so let's continue to decrypt the rest. |
|
| 1105 | $m .= ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( |
|
| 1106 | ParagonIE_Sodium_Core32_Util::substr( |
|
| 1107 | $c, |
|
| 1108 | self::secretbox_xchacha20poly1305_ZEROBYTES |
|
| 1109 | ), |
|
| 1110 | ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), |
|
| 1111 | $subkey, |
|
| 1112 | ParagonIE_Sodium_Core32_Util::store64_le(1) |
|
| 1113 | ); |
|
| 1114 | } |
|
| 1115 | return $m; |
|
| 1116 | } |
|
| 1117 | ||
| 1118 | /** |
|
| 1119 | * Detached Ed25519 signature. |
|