Advertisement
Guest User

ClassGost.php

a guest
Jan 20th, 2016
501
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.16 KB | None | 0 0
  1. <?php
  2.  
  3. /** Êëàññ îñóùåñòâëÿþùèé ðàáîòó ñ øèôðîì ÃÎÑÒ 28147-89 (øèôðîâàíèå/äåøèôðîâàííèå äàííûõ)
  4.  *
  5.  * @author IntSys
  6.  * @copyright Copyright (c) 2011-2013, IntSys, intsystem.org
  7.  */
  8. class ClassGost{
  9.     /** Êîëè÷åñòî èòòåðàöèé îñíîâíîãî øàãà êðèïòîîáðàçîâàíèÿ
  10.      */
  11.     const CNT_MAIN_STEP=32;
  12.  
  13.     /** Òàáëèöà çàìåí
  14.      *
  15.      * @var array
  16.      */
  17.     protected $s_block=array(
  18.         array(6,12,7,1,5,15,13,8,4,10,9,14,0,3,11,2),
  19.         array(14,11,4,12,6,13,15,10,2,3,8,1,0,7,5,9),
  20.         array(13,11,4,1,3,15,5,9,0,10,14,7,6,8,2,12),
  21.         array(7,13,10,1,0,8,9,15,14,4,6,12,11,2,5,3),
  22.         array(1,15,13,0,5,7,10,4,9,2,3,14,6,11,8,12),
  23.         array(4,10,9,2,13,8,0,14,6,11,1,12,7,15,5,3),
  24.         array(4,11,10,0,7,2,1,13,3,6,8,5,9,12,15,14),
  25.         array(5,8,1,13,10,3,4,2,14,15,12,7,6,0,9,11),
  26.  
  27.     );
  28.  
  29.     /** Êëþ÷
  30.      *
  31.      * @var array
  32.      */
  33.     protected $k_block=array (
  34.         0x00000000,
  35.         0x00000000,
  36.         0x00000000,
  37.         0x00000000,
  38.         0x00000000,
  39.         0x00000000,
  40.         0x00000000,
  41.         0x00000000,
  42.     );
  43.  
  44.  
  45.     /** Çàøèôðîâàòü äàííûå
  46.      *
  47.      * @param string $data äàííûå äëÿ øèôðîâàíèÿ
  48.      * @param mixed $key êëþ÷ øèôðîâàíèÿ
  49.      * @param array $table òàáëèöà çàìåí
  50.      * @return mixed âîçâðàùàåò çàøèôðîâàííóþ ñòðîêó, èëè false â ñëó÷àå íåóäà÷è
  51.      */
  52.     function Encode($data, $key=null, $table=null){
  53.         if(!is_null($key)){
  54.             if(!$this->SetKey($key)){
  55.                 return false;
  56.             }
  57.         }
  58.  
  59.         if(!is_null($table)){
  60.             if(!$this->SetTableReplace($table)){
  61.                 return false;
  62.             }
  63.         }
  64.  
  65.         $blocks=$this->LoadData2Blocks($data);
  66.         $keys=$this->LoadKeysArray(self::CNT_MAIN_STEP);
  67.  
  68.         $result='';
  69.  
  70.         foreach($blocks as $block){
  71.             $result.=$this->Global_MainStep($block, $keys);
  72.  
  73.         }
  74.  
  75.         return $result;
  76.     }
  77.  
  78.     /** Ðàñøèôðîâàòü äàííûå
  79.      *
  80.      * @param string $data çàøèôðîâàííûå äàííûå
  81.      * @param mixed $key êëþ÷ øèôðîâàíèÿ
  82.      * @param array $table òàáëèöà çàìåí
  83.      * @return mixed âîçâðàùàåò èñõîäíûå äàííûå, èëè false â ñëó÷àå íåóäà÷è
  84.      */
  85.     function Decode($data, $key=null, $table=null){
  86.         if(!is_null($key)){
  87.             if(!$this->SetKey($key)){
  88.                 return false;
  89.             }
  90.         }
  91.  
  92.         if(!is_null($table)){
  93.             if(!$this->SetTableReplace($table)){
  94.                 return false;
  95.             }
  96.         }
  97.  
  98.         $blocks=$this->LoadData2Blocks($data);
  99.         $keys=array_reverse($this->LoadKeysArray(self::CNT_MAIN_STEP));
  100.  
  101.         $result='';
  102.         foreach($blocks as $block){
  103.             $result.=$this->Global_MainStep($block, $keys);
  104.         }
  105.  
  106.         return $result;
  107.     }
  108.  
  109.     /** Óñòàíîâèòü êëþ÷ øèôðîâàíèÿ<br><br>
  110.      * Âîçìîæíî óêàçàòü êëþ÷ â äâóõ ôîðìàòàõ:<br>
  111.      *  - Ñòðîêà äëèííîé â 32 áàéòà<br>
  112.      *  - Ìàññèâ èç 8 ýëåìåíòîâ, ãäå êàæäûé ýëåìåíò - 4 áàéòîâîå ÷èñëî integer<br><br>
  113.      * Ïðè ýòîì ëþáîå îòêëîíåíèå îò äàííûõ ôîðìàòîâ áóäåò âûçûâàòü îøèáêó
  114.      *
  115.      * @param mixed $key êëþ÷ øèôðîâàíèÿ
  116.      * @return boolen âîçâðàùàåò true åñëè óäàëîñü óñòàíîâèòü êëþ÷ øèôðîâàíèÿ, false - åñëè ïðîèçîøëà îøèáêà
  117.      */
  118.     function SetKey($key){
  119.         if(is_string($key)){
  120.             if(strlen($key)!==32){
  121.                 trigger_error(__METHOD__.': "$key" length must be equal to 256 bits (32 bytes)', E_USER_WARNING);
  122.                 return false;
  123.             }
  124.  
  125.             $new_key=array();
  126.             for($i=0; $i<32; $i+=4){
  127.     //          $tmp=(int)hexdec(bin2hex(substr($key, ($i*4), 4)));
  128.                 $tmp=(int)hexdec(bin2hex(substr($key, ($i), 4)));
  129.                 $new_key[]=$tmp;
  130.             }
  131.  
  132.             $this->k_block=$new_key;
  133.             return true;
  134.         }elseif(is_array($key)){
  135.             if(count($key)!=8){
  136.                 trigger_error(__METHOD__.': count of elements in the array "$key" must be equal to 8', E_USER_WARNING);
  137.                 return false;
  138.             }
  139.             $new_key=array();
  140.             foreach($key as $k => $val){
  141.                 if(!is_integer($val)){
  142.                     trigger_error(__METHOD__.': every element of the array "$key" must be integer. The array element "$table['.htmlspecialchars($k).']" is not an integer.', E_USER_WARNING);
  143.                     return false;
  144.                 }
  145.  
  146.                 $new_key[]=$val;
  147.             }
  148.  
  149.             $this->k_block=$new_key;
  150.             return true;
  151.         }else{
  152.             trigger_error(__METHOD__.': unknown "$Key" format. "$key" must be array[8] of integer or 32-bytes string.', E_USER_WARNING);
  153.             return false;
  154.         }
  155.     }
  156.  
  157.     /** Óñòàíîâèòü òàáëèöó çàìåí.<br>
  158.      * Ôîðìàò òàáëèöû çàìåí - ìàòðèöà ðàçìåðíîñòüþ 8x16,
  159.      * êàæäûé åå ýëåìåíò áîëüøå ëèáî ðàâåí 0 è ìåíüøå ëèáî ðàâåí 15,
  160.      * ïðè ýòîì â êàæäîé ñòðîêå íå äîëæíî áûòü ïîâòîðÿþùèõñÿ çíà÷åíèé.<br><br>
  161.      * Òàêæå îáðàòèòå âíèìàíèå ÷òî íåïðàâèëüíûé âûáîð òàáëèöû çàìåí, ìîæåò
  162.      * ïðèâåñòè ê ñíèæåíèþ ñòîéêîñòè øèôðà.
  163.      *
  164.      * @example
  165.      * Ïðèìåð òàáëèöû:<br>
  166.      * array(6 ,12,7 ,1 ,5 ,15,13,8 ,4 ,10,9 ,14,0 ,3 ,11,2 ),<br>
  167.      * array(14,11,4 ,12,6 ,13,15,10,2 ,3 ,8 ,1 ,0 ,7 ,5 ,9 ),<br>
  168.      * array(13,11,4 ,1 ,3 ,15,5 ,9 ,0 ,10,14,7 ,6 ,8 ,2 ,12),<br>
  169.      * array(7 ,13,10,1 ,0 ,8 ,9 ,15,14,4 ,6 ,12,11,2 ,5 ,3 ),<br>
  170.      * array(1 ,15,13,0 ,5 ,7 ,10,4 ,9 ,2 ,3 ,14,6 ,11,8 ,12),<br>
  171.      * array(4 ,10,9 ,2 ,13,8 ,0 ,14,6 ,11,1 ,12,7 ,15,5 ,3 ),<br>
  172.      * array(4 ,11,10,0 ,7 ,2 ,1 ,13,3 ,6 ,8 ,5 ,9 ,12,15,14),<br>
  173.      * array(5 ,8 ,1 ,13,10,3 ,4 ,2 ,14,15,12,7 ,6 ,0 ,9 ,11),<br>
  174.      *
  175.      * @param array $table òàáëèöà çàìåí
  176.      * @return boolean âîçâðàùàåò true åñëè óäàëîñü óñòàíîâèòü òàáëèöó çàìåí, false- åñëè ïðîèçîøëà îøèáêà
  177.      */
  178.     function SetTableReplace($table){
  179.         if(!is_array($table)){
  180.             trigger_error(__METHOD__.': "$table" must be array', E_USER_WARNING);
  181.             return false;
  182.         }
  183.  
  184.         if(count($table)!=8){
  185.             trigger_error(__METHOD__.': count of elements in the array "$table" must be equal to 8', E_USER_WARNING);
  186.             return false;
  187.         }
  188.  
  189.         $i=0;
  190.         $new_array=array();
  191.         foreach($table as $key => $val){
  192.             if(!is_array($val)){
  193.                 trigger_error(__METHOD__.': $table['.htmlspecialchars($key).'] must be array', E_USER_WARNING);
  194.                 return false;
  195.             }
  196.  
  197.             if(count($val)!=16){
  198.                 trigger_error(__METHOD__.': count of elements in the array "$table['.htmlspecialchars($key).']" must be equal to 16', E_USER_WARNING);
  199.                 return false;
  200.             }
  201.  
  202.  
  203.             $new_val=array();
  204.             foreach($val as $int_key => $int_val){
  205.                 if(!is_integer($int_val)){
  206.                     trigger_error(__METHOD__.': every element of the array "$table['.htmlspecialchars($key).']" must be integer. The array element "$table['.htmlspecialchars($key).']['.htmlspecialchars($int_key).']" is not an integer.', E_USER_WARNING);
  207.                     return false;
  208.                 }
  209.  
  210.                 if($int_val>15 || $int_val<0){
  211.                     trigger_error(__METHOD__.': every element of the array "$table['.htmlspecialchars($key).']" must be greater than or equal to 0 and less than or equal to 15. The array element "$table['.htmlspecialchars($key).']['.htmlspecialchars($int_key).']" is not in this range.', E_USER_WARNING);
  212.                     return false;
  213.                 }
  214.                 $new_val[]=$int_val;
  215.             }
  216.  
  217.             $new_array[$i]=$new_val;
  218.             $i++;
  219.         }
  220.  
  221.  
  222.         $this->s_block=$new_array;
  223.         return true;
  224.     }
  225.  
  226.     /** Îñíîâíîé øàã øèôðîîáðàçîâàíèÿ
  227.      *
  228.      * @param string $block øèôðóåìûé áëîê
  229.      * @param array $keys ïîäãîòîâëåííûé ìàññèâ ñ êëþ÷àìè
  230.      * @param intger $cnt_repeat [îïöèîíàëüíî] êîëè÷åñòâî ïðåîáðàçîâàíèé
  231.      * @return string
  232.      */
  233.     protected function Global_MainStep($block, $keys, $cnt_repeat=self::CNT_MAIN_STEP){
  234.         $this->Global_BlockExplode($block, $n1, $n2);
  235.  
  236.         if(count($keys)<$cnt_repeat){
  237.             $cnt_repeat=count($keys);
  238.         }
  239.  
  240.         for($i=0; $i<$cnt_repeat; $i++){
  241.             $val=$this->Global_SummMod32($n1, $keys[$i]);
  242.  
  243.             $val=$this->Global_BlockReplace($val);
  244.  
  245.             $val=$this->Global_BlockCycleShift($val, 21);
  246.  
  247.             $val=$val ^ $n2;
  248.  
  249.             $n2=$n1;
  250.             $n1=$val;
  251.         }
  252.  
  253.         $this->Global_BlockImplode($block, $n2, $n1);
  254.         return $block;
  255.     }
  256.  
  257.     /** Ôóíêöèÿ öèêëè÷íîãî ïîáèòîâîãî ñäâèãà âïðàâî
  258.      *
  259.      * @param integer $block
  260.      * @param integer $bits êîëè÷åñòâî áèòîâ äëÿ ñäâèãà
  261.      * @return integer
  262.      */
  263.     protected function Global_BlockCycleShift($block, $bits){
  264.         if($bits>0){
  265.             $a=$bits;
  266.             $b=32-$a;
  267.             $block=(($block >> $a) & ~(-pow(2,$b)))^($block << $b);
  268.         }
  269.         return $block;
  270.     }
  271.  
  272.     /** Çàìåíà ïî òàáëèöå çàìåí
  273.      *
  274.      * @param integer $block òåêóùèé áëîê äëÿ çàìåíû
  275.      * @return integer
  276.      */
  277.     protected function Global_BlockReplace($block){
  278.         $new_block=0;
  279.  
  280.         for($i=0; $i<8; $i++){
  281.             //Âû÷ëåíÿåì íóæíûå 4 áèòà ïîä çàìåíó
  282.             $rem=$block>>(4*($i+1));
  283.             $rem=$rem<<(4*($i+1));
  284.  
  285.             if($i==7){
  286.                 $hex=$rem;
  287.             }else{
  288.                 $hex=$block-$rem;
  289.                 $block=$rem;
  290.             }
  291.  
  292.             $hex=$this->Global_BlockCycleShift($hex,(4*$i));
  293.  
  294.             //Íàõîäèì íà êàêîå ÷èñëî åãî çàìåíÿòü ïî òàáëèöå çàìåí
  295.             $replace=$this->s_block[$i][$hex];
  296.  
  297.             //Çàìåíÿåì
  298.             $new_block=$new_block + (pow(16, $i)*$replace);
  299.         }
  300.  
  301.         return $new_block;
  302.     }
  303.  
  304.     /** Ñóììèðîâàíèå äâóõ ÷èñåë ïî ìîäóëþ 32
  305.      *
  306.      * @param integer $bin1 ÷èñëî (4 áàéòà)
  307.      * @param integer $bin2 ÷èñëî (4 áàéòà)
  308.      * @return integer ðåçóëüòàò âû÷èñëåíèÿ (4 áàéòà)
  309.      */
  310.     protected function Global_SummMod32($bin1, $bin2){
  311.         $summ=$this->NormalizeInteger32(intval($bin1 + $bin2));
  312.  
  313.         return $summ;
  314.     }
  315.  
  316.     /** Ðàçáèåíèå áëîêà íà "ïðàâóþ" è "ëåâóþ" ÷àñòü
  317.      *
  318.      * @param string $block âõîäíîé áëîê (8 áàéò)
  319.      * @param &integer $left ëåâàÿ ÷àñòü (íàêîïèòåëü N1) (4 áàéòà)
  320.      * @param &integer $right ïðàâàÿ ÷àñòü (íàêîïèòåëü N2) (4 áàéòà)
  321.      */
  322.     protected function Global_BlockExplode($block, &$left, &$right){
  323.         $left='';
  324.         $right='';
  325.  
  326.         $left=substr($block, 0, 4);
  327.         $right=substr($block, 4, 4);
  328.  
  329.         $left =hexdec(bin2hex($left ));
  330.         $right=hexdec(bin2hex($right));
  331.     }
  332.  
  333.     /** Ðàçáèåíèå áëîêà íà "ïðàâóþ" è "ëåâóþ" ÷àñòü
  334.      *
  335.      * @param &string $block âõîäíîé áëîê (8 áàéò)
  336.      * @param integer $left ëåâàÿ ÷àñòü (íàêîïèòåëü N1) (4 áàéòà)
  337.      * @param integer $right ïðàâàÿ ÷àñòü (íàêîïèòåëü N2) (4 áàéòà)
  338.      */
  339.     protected function Global_BlockImplode(&$block, $left, $right){
  340.         $left =sprintf("%08x", $left );
  341.         $right=sprintf("%08x", $right);
  342.  
  343.         $block='';
  344.  
  345.         $arr=str_split($left, 2);
  346.         foreach($arr as $hex){
  347.             $block.=chr(hexdec($hex));
  348.         }
  349.  
  350.         $arr=str_split($right, 2);
  351.         foreach($arr as $hex){
  352.             $block.=chr(hexdec($hex));
  353.         }
  354.     }
  355.  
  356.     /** Ãåíåðèðóåì ìàññèâ ñ êëþ÷àìè
  357.      *
  358.      * @param integer $cnt_repeat êîëè÷åñòâî êëþ÷åé
  359.      * @return array
  360.      */
  361.     protected function LoadKeysArray($cnt_repeat=self::CNT_MAIN_STEP){
  362.         $key_block=array();
  363.         for($i=0; $i<$cnt_repeat; $i++){
  364.             if($i<($cnt_repeat-8)){
  365.                 $x=$i % 8;
  366.             }else{
  367.                 $x=7 - ($i % 8);
  368.             }
  369.             $key_block[]=$this->k_block[$x];
  370.         }
  371.  
  372.         return $key_block;
  373.     }
  374.  
  375.     /** Ðàçáèâàåì äàííûå íà áëîêè ïî 64 áèòà (8 áàéò)
  376.      *
  377.      * @param string $data âõîäíûå äàííûå
  378.      * @param integer $block_size [îïöèîíàëüíî] (64 - äåôîëò) ðàçìåðíîñòü áëîêîâ
  379.      * @return array âûõîäíîé ìàññèâ ñ áëîêàìè
  380.      */
  381.     protected function LoadData2Blocks($data, $block_size=64){
  382.         $blocks=array();
  383.  
  384.         $block_len=(int)$block_size / 8;
  385.  
  386.         for($i=0, $x=(ceil(strlen($data)/$block_len)); $i<$x; $i++){
  387.             $blocks[$i]=substr($data, ($i*$block_len), $block_len);
  388.  
  389.             if($i==($x-1)){
  390.                 //Åñëè ïîñëåäíèé áëîê íå ïîëîí, òî äîïîëíÿåì åãî íóëÿìè
  391.                 $blocks[$i]=str_pad($blocks[$i], $block_len, chr(0), STR_PAD_RIGHT);
  392.  
  393.             }
  394.         }
  395.  
  396.         return $blocks;
  397.     }
  398.  
  399.     /** Ïðåâåäåíèå 64áèòíîãî integer ê "32áèòíîìó" íà 64áèòíûõ ñèñòåìàõ
  400.      *
  401.      * @param integer $number
  402.      */
  403.     private function NormalizeInteger32($number){
  404.         static $is_64bit=null;
  405.  
  406.         $number=intval($number);
  407.  
  408.         if(is_null($is_64bit)){
  409.             if(intval(2147483647+1)>0){
  410.                 $is_64bit=true;
  411.             }else{
  412.                 $is_64bit=false;
  413.             }
  414.         }
  415.  
  416.         if($is_64bit){
  417.             static $int=null;
  418.  
  419.             if(is_null($int)){
  420.                 $int=0;
  421.  
  422.                 //Ãåíåðèðóåì ÷èñëî ó êîòîðîãî â äâîè÷íîì ïðåäñòàâëåíèè ìëàäøèå 32 áèòà - åäèíèöû, îñòàëüíûå - íóëè
  423.                 //
  424.                 // 32-áèòíûõ ñèñòåìàõ ýòî ÷èñëî "-1"
  425.                 //Â 64-áèòíûõ - "4294967295"
  426.                 for($i=0; $i<32; $i++){
  427.                     $int=$int | (1<<$i);
  428.                 }
  429.             }
  430.  
  431.             //Ïîáèòîâîå AND
  432.             $number=intval($number & $int);
  433.         }
  434.  
  435.         return $number;
  436.     }
  437. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement