<? 
include "keyakv2.php"; 
/* 
LakeKeyak can absorb up to 192 bytes of metadata per call to f  
or up to 168 of plaintext, with additionally 24 bytes of metadata 
 
, up to 150 bytes of nonce 
*/ 
 
class Sender 
    { 
    function __construct ($K, $N, $tagFlag, $decryptFlag, $forgetFlag) 
        { 
    $this->T = new stringStream;        
        $this->k = new Keyak("Lake"); 
        $status  = $this->k->StartEngine($K, $N,  $tagFlag, $this->T, $decryptFlag, $forgetFlag); 
    } 
    function sendAEADMsg($message, $metadata, $decryptFlag, $forgetFlag) 
        { 
        $I = new stringStream($message); 
        $A = new stringStream($metadata); 
        $O = new stringStream; 
        $status = $this->k->Wrap($I, $O, $A, $this->T, $decryptFlag, $forgetFlag); 
        return [bin2hex($O->getvalue()), bin2hex($this->T->getvalue()), $status]; 
    } 
    } 
                   
class Receiver 
    { 
    function __construct($K, $N, $tagFlag, $unwrapFlag, $forgetFlag) 
        { 
        $this->k = new Keyak("Lake"); 
        $this->T = new stringStream;  
        $status  = $this->k->StartEngine($K, $N, $tagFlag, $this->T, $unwrapFlag, $forgetFlag); 
    } 
    function recvAEADMsg($cipher, $metadata, $unwrapFlag_W, $forgetFlag, $T="") 
        { 
    $O = new stringStream; 
        $I = new stringStream($cipher); 
        $A = new stringStream($metadata); 
    if ($T) 
    $this->T = new stringStream($T);  
    else $this->T=new stringStream;          
        $status  = $this->k->Wrap($I, $O, $A, $this->T, $unwrapFlag_W, $forgetFlag); 
        return [bin2hex($O->getvalue()), $status]; 
    } 
    }     
 
$bool    = ["False"=>0,"false"=>0,"True"=>1]; 
$vectors = array_slice(explode('*** Keyak',file_get_contents("https://github.com/samvartaka/keyak-python/raw/master/TestVectors/LakeKeyak.txt")),1); 
 
foreach ($vectors as $vector) 
{ 
$K         = pack("H*",explode(']',explode('> K: [',$vector)[1])[0]); 
$N         = pack("H*",explode(']',explode('> N: [',$vector)[1])[0]); 
$T_valid    = explode(']',@explode('< T (tag): [',explode('Wrap',$vector)[0])[1])[0]; 
$engine     = explode(')',explode('StartEngine(K, N,',$vector)[1])[0]; 
$tagFlag    = $bool[explode(',',explode('tagFlag=',$engine)[1])[0]]; 
$unwrapFlag = $bool[explode(',',explode('unwrapFlag=',$engine)[1])[0]]; 
$forgetFlag = $bool[explode('forgetFlag=',$engine)[1]]; 
 
$sender     = new Sender($K, $N,  $tagFlag, $unwrapFlag, $forgetFlag);     
 
$wraps      = array_slice(explode('Wrap(I, O, A, T,',$vector),1); 
 
foreach ($wraps as $wrap) 
    {     
    $A         = pack("H*",explode(']',explode('> A (metadata): [',$wrap)[1])[0]); 
    $I         = pack("H*",explode(']',explode('> I (plaintext): [',$wrap)[1])[0]);     
    $O_valid     = explode(']',explode('< O (ciphertext): [',$wrap)[1])[0]; 
    $T_valid_wrap     = explode(']',explode('< T (tag): [',$wrap)[1])[0]; 
     
    $wrap         = explode(")",$wrap)[0]; 
         
    $unwrapFlag_W     = $bool[explode(',',explode('unwrapFlag=',$wrap)[1])[0]];     
    $forgetFlag_W     = $bool[explode('forgetFlag=',$wrap)[1]]; 
         
    echo "\nCiphering ".bin2hex($I)."\n"; 
         
    [$O,$T,$status] = $sender->sendAEADMsg($I, $A, $unwrapFlag_W, $forgetFlag_W); 
     
    echo "Cipher   $O\nExpected $O_valid\nTag      $T\nExpected $T_valid_wrap\n\n"; 
     
    if ($O == $O_valid and $T == $T_valid_wrap) echo "Ok\n"; 
    else          
        die("\n Bad Cipher");     
    } 
} 
 
 |