[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 declare(strict_types=1); 3 namespace ParagonIE\ConstantTime; 4 5 use RangeException; 6 use TypeError; 7 8 /** 9 * Copyright (c) 2016 - 2022 Paragon Initiative Enterprises. 10 * Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com) 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a copy 13 * of this software and associated documentation files (the "Software"), to deal 14 * in the Software without restriction, including without limitation the rights 15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 * copies of the Software, and to permit persons to whom the Software is 17 * furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be included in all 20 * copies or substantial portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 * SOFTWARE. 29 */ 30 31 /** 32 * Class Hex 33 * @package ParagonIE\ConstantTime 34 */ 35 abstract class Hex implements EncoderInterface 36 { 37 /** 38 * Convert a binary string into a hexadecimal string without cache-timing 39 * leaks 40 * 41 * @param string $binString (raw binary) 42 * @return string 43 * @throws TypeError 44 */ 45 public static function encode(string $binString): string 46 { 47 $hex = ''; 48 $len = Binary::safeStrlen($binString); 49 for ($i = 0; $i < $len; ++$i) { 50 /** @var array<int, int> $chunk */ 51 $chunk = \unpack('C', $binString[$i]); 52 $c = $chunk[1] & 0xf; 53 $b = $chunk[1] >> 4; 54 55 $hex .= \pack( 56 'CC', 57 (87 + $b + ((($b - 10) >> 8) & ~38)), 58 (87 + $c + ((($c - 10) >> 8) & ~38)) 59 ); 60 } 61 return $hex; 62 } 63 64 /** 65 * Convert a binary string into a hexadecimal string without cache-timing 66 * leaks, returning uppercase letters (as per RFC 4648) 67 * 68 * @param string $binString (raw binary) 69 * @return string 70 * @throws TypeError 71 */ 72 public static function encodeUpper(string $binString): string 73 { 74 $hex = ''; 75 $len = Binary::safeStrlen($binString); 76 77 for ($i = 0; $i < $len; ++$i) { 78 /** @var array<int, int> $chunk */ 79 $chunk = \unpack('C', $binString[$i]); 80 $c = $chunk[1] & 0xf; 81 $b = $chunk[1] >> 4; 82 83 $hex .= \pack( 84 'CC', 85 (55 + $b + ((($b - 10) >> 8) & ~6)), 86 (55 + $c + ((($c - 10) >> 8) & ~6)) 87 ); 88 } 89 return $hex; 90 } 91 92 /** 93 * Convert a hexadecimal string into a binary string without cache-timing 94 * leaks 95 * 96 * @param string $encodedString 97 * @param bool $strictPadding 98 * @return string (raw binary) 99 * @throws RangeException 100 */ 101 public static function decode( 102 string $encodedString, 103 bool $strictPadding = false 104 ): string { 105 $hex_pos = 0; 106 $bin = ''; 107 $c_acc = 0; 108 $hex_len = Binary::safeStrlen($encodedString); 109 $state = 0; 110 if (($hex_len & 1) !== 0) { 111 if ($strictPadding) { 112 throw new RangeException( 113 'Expected an even number of hexadecimal characters' 114 ); 115 } else { 116 $encodedString = '0' . $encodedString; 117 ++$hex_len; 118 } 119 } 120 121 /** @var array<int, int> $chunk */ 122 $chunk = \unpack('C*', $encodedString); 123 while ($hex_pos < $hex_len) { 124 ++$hex_pos; 125 $c = $chunk[$hex_pos]; 126 $c_num = $c ^ 48; 127 $c_num0 = ($c_num - 10) >> 8; 128 $c_alpha = ($c & ~32) - 55; 129 $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; 130 131 if (($c_num0 | $c_alpha0) === 0) { 132 throw new RangeException( 133 'Expected hexadecimal character' 134 ); 135 } 136 $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0); 137 if ($state === 0) { 138 $c_acc = $c_val * 16; 139 } else { 140 $bin .= \pack('C', $c_acc | $c_val); 141 } 142 $state ^= 1; 143 } 144 return $bin; 145 } 146 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body