summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorParagon Initiative Enterprises <security@paragonie.com>2016-02-02 20:42:59 -0500
committerScott <scott@paragonie.com>2016-02-02 20:42:59 -0500
commit92f2056256c8afd150b44b7dd7dcd7c4637eacea (patch)
tree864f624825430ef26f51a6062bfc63fa05487bf2
parent4881414045dcfc408ba0fa10023ffb473c9dcb1d (diff)
downloadconstant_time_encoding-92f2056256c8afd150b44b7dd7dcd7c4637eacea.zip
constant_time_encoding-92f2056256c8afd150b44b7dd7dcd7c4637eacea.tar.gz
constant_time_encoding-92f2056256c8afd150b44b7dd7dcd7c4637eacea.tar.bz2
Add hex encoding/decoding
-rw-r--r--src/Encoding.php59
1 files changed, 58 insertions, 1 deletions
diff --git a/src/Encoding.php b/src/Encoding.php
index 3324b34..81983c2 100644
--- a/src/Encoding.php
+++ b/src/Encoding.php
@@ -336,6 +336,63 @@ class Encoding
}
/**
+ * Convert a binary string into a hexadecimal string without cache-timing
+ * leaks
+ *
+ * @param string $bin_string (raw binary)
+ * @return string
+ */
+ public static function hexEncode($bin_string)
+ {
+ $hex = '';
+ $len = self::safeStrlen($bin_string);
+ for ($i = 0; $i < $len; ++$i) {
+ $c = \ord($bin_string[$i]) & 0xf;
+ $b = \ord($bin_string[$i]) >> 4;
+ $hex .= \chr(87 + $b + ((($b - 10) >> 8) & ~38));
+ $hex .= \chr(87 + $c + ((($c - 10) >> 8) & ~38));
+ }
+ return $hex;
+ }
+
+ /**
+ * Convert a hexadecimal string into a binary string without cache-timing
+ * leaks
+ *
+ * @param string $hex_string
+ * @return string (raw binary)
+ */
+ public static function hexDecode($hex_string)
+ {
+ $hex_pos = 0;
+ $bin = '';
+ $hex_len = self::safeStrlen($hex_string);
+ $state = 0;
+
+ while ($hex_pos < $hex_len) {
+ $c = \ord($hex_string[$hex_pos]);
+ $c_num = $c ^ 48;
+ $c_num0 = ($c_num - 10) >> 8;
+ $c_alpha = ($c & ~32) - 55;
+ $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8;
+ if (($c_num0 | $c_alpha0) === 0) {
+ throw new \RangeException(
+ 'hexEncode() only expects hexadecimal characters'
+ );
+ }
+ $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0);
+ if ($state === 0) {
+ $c_acc = $c_val * 16;
+ } else {
+ $bin .= \chr($c_acc | $c_val);
+ }
+ $state = $state ? 0 : 1;
+ ++$hex_pos;
+ }
+ return $bin;
+ }
+
+ /**
*
* Base64 character set:
* [A-Z] [a-z] [0-9] + /
@@ -487,7 +544,7 @@ class Encoding
* @param string $str
* @return int
*/
- public static function safeStrlen($str)
+ protected static function safeStrlen($str)
{
if (\function_exists('mb_strlen')) {
return \mb_strlen($str, '8bit');