# Review my Diffie Hellman class

Here is a link to my project, more details regarding the Diffie Hellman Key Exchange using MODP cyclic grous are available here, no ECP currently implemented

https://en.wikipedia.org/wiki/Diffie_hellman

I would like to know if I my code could be improved or if the BCMath implementation can pe significantly improved, because :

Using groups defined in available RFCs

• GMP code is very fast
• Group 2 : 0.03 ~ 0.05 seconds
• BCMath implementation is slow
• Group 2 : 10 ~ 15 seconds

https://github.com/cristib89/diffie-hellman

Calculation time grows exponentially as the size of the group increases

Later edit : source code below

Usage example

    <?php

require "DiffieHellmanBC.inc.php";
require "DiffieHellmanGMP.inc.php";
require "MathUtils.inc.php";

set_time_limit(0);

$start = microtime(true);$d1 = new DiffieHellmanGMP();
$d1->usePredefinedGroup("group2");$d2 = new DiffieHellmanGMP();
$d2->usePredefinedGroup("group2");$aux = $d1->sendLocalPublicKey();$d2->receiveRemotePublicKey($aux);$aux = $d2->sendLocalPublicKey();$d1->receiveRemotePublicKey($aux);$a=$d1->calculateSharedSecretKey();$b=$d2->calculateSharedSecretKey(); echo "<hr/>GMP implementation <hr/>"; iF($a==$b) echo "OK"; else echo "NOK"; echo "<br/>"; print_r($d1->diagnose());
echo "<br/>";
print_r($d2->diagnose()); echo "<br/>"; echo hash("SHA1",$a);
echo "<br/>";
echo hash("SHA256",$a); echo "<br/>"; echo hash("SHA512",$a);
echo "<br/>";

$end = microtime(true); echo ($end-$start)." seconds";$start = microtime(true);

$d1 = new DiffieHellmanBC();$d1->usePredefinedGroup("group2");

$d2 = new DiffieHellmanBC();$d2->usePredefinedGroup("group2");

$aux =$d1->sendLocalPublicKey();
$d2->receiveRemotePublicKey($aux);
$aux =$d2->sendLocalPublicKey();
$d1->receiveRemotePublicKey($aux);

$a=$d1->calculateSharedSecretKey();
$b=$d2->calculateSharedSecretKey();

echo "<hr/>BCMath implementation <hr/>";
iF($a==$b) echo "OK"; else echo "NOK";

echo "<br/>";
print_r($d1->diagnose()); echo "<br/>"; print_r($d2->diagnose());

echo "<br/>";
echo hash("SHA1",$a); echo "<br/>"; echo hash("SHA256",$a);
echo "<br/>";
echo hash("SHA512",$a); echo "<br/>";$end = microtime(true);
echo ($end-$start)."seconds";

?>


BCMath implementation

<?php

class DiffieHellmanBC{

private $group = array("prime"=>"", "generator"=>""); private$localPrivateKey, $localPublicKey,$remotePublicKey;
private $sharedSecretKey; private$mathutils;

/*
* predefined groups
*/
private $groups = array( "testGroup"=>array("prime"=>"17","generator"=>"5"), "group1"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF","generator"=>"2"), "group2"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF","generator"=>"2"), "group5"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF","generator"=>"2"), "group14"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF","generator"=>"2"), "group15"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF","generator"=>"2"), "group16"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF","generator"=>"2"), "group17"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF","generator"=>"2"), "group18"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF","generator"=>"2"), "group22"=>array("prime"=>"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371","generator"=>"A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5"), "group23"=>array("prime"=>"AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC2129037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708B3BF8A317091883681286130BC8985DB1602E714415D9330278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486DCDF93ACC44328387315D75E198C641A480CD86A1B9E587E8BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71CF9DE5384E71B81C0AC4DFFE0C10E64F","generator"=>"AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFAAB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7C17669101999024AF4D027275AC1348BB8A762D0521BC98AE247150422EA1ED409939D54DA7460CDB5F6C6B250717CBEF180EB34118E98D119529A45D6F834566E3025E316A330EFBB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC017981BC087F2A7065B384B890D3191F2BFA"), "group24"=>array("prime"=>"87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597","generator"=>"3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659") ); public function __construct(){$this->mathutils = new MathUtils();
}

public function getGroup(){
/*
* returns current public group
*/
return $this->group; } public function setGroup($group){
/*
* sets public group
*/
$this->group["prime"] =$group["prime"];
$this->group["generator"] =$group["generator"];
}

public function getPrime(){
return $this->group["prime"]; } public function getGenerator(){ return$this->group["generator"];
}

public function setPrime($num){$this->group["prime"] = $num; } public function setGenerator($num){
$this->group["generator"] =$num;
}

public function getPredefinedGroups(){
/*
* returns predefined groups
*/
return $this->groups; } public function usePredefinedGroup($group){
/*
* use a predefined group
*/
$this->setGroup($this->groups[$group]); } public function getLocalPrivateKey(){ return$this->localPrivateKey;
}

public function getLocalPublicKey(){
return $this->localPublicKey; } public function getRemotePublicKey(){ return$this->remotePublicKey;
}

public function setLocalPrivateKey($num){$this->localPrivateKey = $num; } public function setLocalPublicKey($num){
$this->localPublicKey =$num;
}

public function setRemotePublicKey($num){$this->remotePublicKey = $num; } public function sendLocalPublicKey(){ /* * stores localPrivateKey and returns localPublicKey */$prime = $this->mathutils->bchexdec($this->getPrime());
$generator =$this->mathutils->bchexdec($this->getGenerator());$this->localPrivateKey = $this->mathutils->bcrandom("1",$prime);
$this->localPublicKey = bcpowmod($generator,$this->localPrivateKey,$prime);
return $this->localPublicKey; } public function receiveRemotePublicKey($remotePublicKey){
/*
* gets remotePublicKey, used for calculation of sharedSecretKey
*/
$this->remotePublicKey =$remotePublicKey;
}

public function calculateSharedSecretKey(){
/*
* calculates sharedSecretKey
*/
$prime =$this->mathutils->bchexdec($this->getPrime());$this->sharedSecretKey = bcpowmod($this->remotePublicKey,$this->localPrivateKey,$prime); return$this->sharedSecretKey;
}

/*
* deletes data from memory
*/
$this->localPrivateKey = "";$this->localPublicKey = "";
$this->remotePublicKey = "";$this->sharedSecretKey = "";
}

public function diagnose(){

return array($this->localPrivateKey,$this->localPublicKey,$this->remotePublicKey,$this->sharedSecretKey);

}

}

?>


GMP implementation

<?php

class DiffieHellmanGMP{

private $group = array("prime"=>"", "generator"=>""); private$localPrivateKey, $localPublicKey,$remotePublicKey;
private $sharedSecretKey; private$mathutils;

/*
* predefined groups
*/
private $groups = array( "testGroup"=>array("prime"=>"17","generator"=>"5"), "group1"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF","generator"=>"2"), "group2"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF","generator"=>"2"), "group5"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF","generator"=>"2"), "group14"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF","generator"=>"2"), "group15"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF","generator"=>"2"), "group16"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF","generator"=>"2"), "group17"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF","generator"=>"2"), "group18"=>array("prime"=>"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF","generator"=>"2"), "group22"=>array("prime"=>"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371","generator"=>"A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5"), "group23"=>array("prime"=>"AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC2129037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708B3BF8A317091883681286130BC8985DB1602E714415D9330278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486DCDF93ACC44328387315D75E198C641A480CD86A1B9E587E8BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71CF9DE5384E71B81C0AC4DFFE0C10E64F","generator"=>"AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFAAB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7C17669101999024AF4D027275AC1348BB8A762D0521BC98AE247150422EA1ED409939D54DA7460CDB5F6C6B250717CBEF180EB34118E98D119529A45D6F834566E3025E316A330EFBB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC017981BC087F2A7065B384B890D3191F2BFA"), "group24"=>array("prime"=>"87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597","generator"=>"3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659") ); public function __construct(){$this->mathutils = new MathUtils();
}

public function getGroup(){
/*
* returns current public group
*/
return $this->group; } public function setGroup($group){
/*
* sets public group
*/
$this->group["prime"] =$group["prime"];
$this->group["generator"] =$group["generator"];
}

public function getPrime(){
return $this->group["prime"]; } public function getGenerator(){ return$this->group["generator"];
}

public function setPrime($num){$this->group["prime"] = $num; } public function setGenerator($num){
$this->group["generator"] =$num;
}

public function getPredefinedGroups(){
/*
* returns predefined groups
*/
return $this->groups; } public function usePredefinedGroup($group){
/*
* use a predefined group
*/
$this->setGroup($this->groups[$group]); } public function getLocalPrivateKey(){ return$this->localPrivateKey;
}

public function getLocalPublicKey(){
return $this->localPublicKey; } public function getRemotePublicKey(){ return$this->remotePublicKey;
}

public function setLocalPrivateKey($num){$this->localPrivateKey = $num; } public function setLocalPublicKey($num){
$this->localPublicKey =$num;
}

public function setRemotePublicKey($num){$this->remotePublicKey = $num; } public function sendLocalPublicKey(){ /* * stores localPrivateKey and returns localPublicKey */$prime = $this->mathutils->gmphexdec($this->getPrime());
$generator =$this->mathutils->gmphexdec($this->getGenerator());$this->localPrivateKey = $this->mathutils->gmprandom("1",$prime);
$this->localPublicKey = gmp_strval(gmp_powm($generator,$this->localPrivateKey,$prime));
return $this->localPublicKey; } public function receiveRemotePublicKey($remotePublicKey){
/*
* gets remotePublicKey, used for calculation of sharedSecretKey
*/
$this->remotePublicKey = gmp_strval($remotePublicKey);
}

public function calculateSharedSecretKey(){
/*
* calculates sharedSecretKey
*/
$prime =$this->mathutils->gmphexdec($this->getPrime());$this->sharedSecretKey = gmp_strval(gmp_powm($this->remotePublicKey,$this->localPrivateKey,$prime)); return$this->sharedSecretKey;
}

public function diagnose(){

return array($this->localPrivateKey,$this->localPublicKey,$this->remotePublicKey,$this->sharedSecretKey);

}

/*
* deletes data from memory
*/
$this->localPrivateKey = "";$this->localPublicKey = "";
$this->remotePublicKey = "";$this->sharedSecretKey = "";
}

}

?>

-
You should add your code directly in your post, per FAQ. Otherwise you risk having your question being closed as off topic. – mseancole Dec 26 '12 at 17:11
I'd worry abound timing side-channel attacks. Cryptographic code needs constant time operations, general purpose math library are typically variable time. Such leaks can allow an attacker to figure out your private key. This has happened to older OpenSSL versions. – CodesInChaos Feb 4 '13 at 15:17

Just a heads up: You don't have to include the ".php" extension on ".inc" files. They are typically considered separate extensions. The ".inc" extension usually indicates a file to be included, such as a template file, not a class file. However, this is probably more of a point of preference rather than standard. It is merely something I have observed and adopted in my own work.

You should avoid manipulating the time limit. If your application requires you to modify that value, then you should know something is wrong. The reason this should be avoided is because you cause your server to hang while it waits for the application to finish and this can easily mask issues such as infinite loops. Typically the thing to do here is to limit how much work you are doing. Another option is to attempt to refactor your code to speed up the processing. In the end it just depends on your circumstances.

There is an essential OOP principle you are neglecting in your usage example: "Don't Repeat Yourself" (DRY). As the name implies, your code should not repeat itself. From everything I can gather you are creating two very similar instances of the DiffieHellmanGMP class. There is an adage that says, "You can either do something once, or many times; There is no such thing as doing something only twice." I probably slaughtered that quote, but you get the idea. The adage and principle go hand in hand. So in this instance, the ideal thing to do is to create a loop to instantiate each instance. And since we should know variable-variables are bad, we will instead use an array to store our instances.

$instances = array();$numInstances = 2;
for( $i = 0;$i < $numInstances;$i++ ) {
$instance = new DiffieHellmanGMP();$instance->usePredefinedGroup( 'group2' );

$aux =$instance->sendLocalPublicKey();
$instance->receiveRemotePublicKey($aux );

$secretKey =$instance->calculateSharedSecretKey();

//finish instantiating...

$savedInstance = compact( 'instance', 'secretKey', etc... );$instances[ $i ] =$savedInstance;
}


Another point of contention here is the use of HTML in your PHP. I would avoid this if at all possible, especially if that HTML is static. I don't know of any IDEs that support proper tag matching/highlighting with embedded HTML, and its always better, in my opinion, to have the logic separated from the display as they are separate concerns. So an alternative here is to escape temporarily from PHP to output your HTML, or, more ideally, you can separate it entirely by creating a template. For example:

$encryption = array( 'SHA1', 'SHA256', 'SHA512' ); foreach($encryption as $crypt ) { echo hash($crypt, $a ); ?> <br /> <?php } //or in another file you include in its place <?php foreach($encryption as $crypt ) : ?> <?php echo hash($crypt, $a ); ?> <br /> <?php endforeach; ?>  That's kind of a bad example because of how little HTML is being output, but it gives you an idea. Another possibility here, though one I wouldn't be too fond of, is to use nl2br(), to create those newlines for you. I only mention it because of how frequently you seem to add those breaks. Please, always use braces. For one thing, they reduce the likelihood of making a mistake, and for another they can be confusing, especially to those who have never seen the syntax before and don't understand the pitfalls. if($a == $b ) { echo "OK"; } else { echo "NOK"; }  Another option would be to use a ternary statement if you are insistent upon single line statements. Don't go overboard with these, ternary statements are meant to be an aid, not a hindrance, and they should never detract from legibility. Not everyone likes these, but I do find them useful for small and simple tasks such as this. echo$a == $b ? 'OK' : 'NOK';  It appears that you are attempting to use doccomments here, otherwise you should just use the double forward slash to initiate a normal, single line, comment. However, I'm not suggesting you use normal comments, just trying to explain the difference. If your code is self-documenting you should only ever need doccomments. Doccomments have two asterisks to begin them and they should always be before the element they are to document. I notice that some of your comments are internal to the methods. These will not work as doccomments, even if they did have the correct syntax. /** short desc. * * long * description * * @param * @return * etc... */  Alright, I'm not going to even begin to hazard a guess as to what those long alpha-numeric strings are supposed to be, but you might think about saving those values to a database of some sort. You can use anything: A simple text file, JSON, MySQL, and XML to name but a few. But they only add clutter here and that should be avoided. Store them somewhere, then retrieve them when needed. You should consider injecting your dependencies to avoid tight coupling. This is one of the major benefits of an OOP design. Doing this will make any future expansion easier. For instance, in the below snippet I require that the injected value be of the MathUtils family. That doesn't mean it has to be the MathUtils class, only that it be related to it. This means that should the MathUtils class ever be expanded, then that class can then be injected instead and should work seamlessly with this one. public function __construct( MathUtils$mathutils ) {
$this->mathutils =$mathutils;
}


Always verify that your public methods accept only those values that you expect. In your setGroup() method you aren't doing this. That means that the $group I could inject into this could be a string, or integer, or some other class even. Using type hinting will prevent any other type of value from being injected other than those that you want. public function setGroup( Array$group ) {


Another thing you will want to verify is that the array being passed to setGroup() has the right elements. Your code is just assuming that it will have the prime and generator elements and never checks for them. This can cause issues, especially with a public method. Public methods are almost like user information from a form. You should always verify it.

SNIPPED TO EDITED SECTION

Now, I don't know what is causing your speed issues. The code you provided doesn't seem to be so inefficient, except for the DRY references I made. But then again, I think your issue might not be in either of these classes, but rather in one of the other ones; Such as the MathUtils class. To get a better idea of where the culprit might be, you should probably profile every action to determine where the most time is being eaten up. Apply the advice in this answer to whatever you find. More than likely its a DRY issue, or its just that you are attempting to do too much.

The only other advice I have that might interest you is a suggestion to take a look into using the magic getter and setter methods. Most of your get*() and set*() methods appear to use the $group property array. If you set up your getter and setter methods to automatically use this array, then you can avoid having to write each getter and setter manually. For instance, here's how the getter might look: public function __get($key ) {
return isset( $this->group[$key ] ) ? $this->group[$key ] : FALSE;
}


Now, you're not going to be able to use that for everything obviously, but that should definitely alleviate the worst of it. Then again, this is something some people don't like to use, so it is entirely up to you.

EDIT

You should consider combining your DiffieHellmanBC and DiffieHellmanGMP classes into a base class to extend from. And if you make the base class an abstract class, you can add abstract methods for those methods of the same name that differ between the versions to create a common interface. This will allow for future expansion and reduces the amount of repeated code, following DRY. The advantage of extending the class means that you don't have to repeat all of those things they have in common, instead they will be inherited by any class that extends it. The only thing you will really have to change is all of those private properties. Protected is almost identical to private except that a protected element is shared with any child classes whereas private remains invisible.

abstract class DiffieHellman {
protected $group = array("prime"=>"", "generator"=>""); protected$localPrivateKey, $localPublicKey,$remotePublicKey;
protected $sharedSecretKey; protected$mathutils;

protected $groups = array( //etc... ); public function __construct( MathUtils$mathutils ) {
$this->mathutils =$mathutils;
}

//etc...

/**
* Another advantage to base classes, especially abstract ones,
* is the ability to get the doccomments out of the way.
* This is essentially the application's API.
*/
abstract public function sendLocalPublicKey();
}

class DiffieHellmanBC extends DiffieHellman {
//no need to redefine the properties or constructor.
//just add anything specific to this class for example:

public function sendLocalPublicKey(){
$prime =$this->mathutils->bchexdec($this->getPrime());$generator = $this->mathutils->bchexdec($this->getGenerator());
$this->localPrivateKey =$this->mathutils->bcrandom("1",$prime);$this->localPublicKey = bcpowmod($generator,$this->localPrivateKey, $prime); return$this->localPublicKey;
}
}

class DiffieHellmanGMP extends DiffieHellman {
//no need to redefine the properties or constructor.
//just add anything specific to this class for example:

public function sendLocalPublicKey(){
$prime =$this->mathutils->gmphexdec($this->getPrime());$generator = $this->mathutils->gmphexdec($this->getGenerator());
$this->localPrivateKey =$this->mathutils->gmprandom("1",$prime);$this->localPublicKey = gmp_strval(gmp_powm($generator,$this->localPrivateKey, $prime)); return$this->localPublicKey;
}
}


I still say your problem is not here, but is in the MathUtils class. If you want to know what is causing all the issues, I suggest you profile your MathUtils methods. After you track down the offending methods you can post just those to see if anyone has any other suggestions. Though I suggest if you do that you do so in a new question to preserve this one. However, if, as you say, the BC math version has been proven less efficient, then there isn't much to be done except refactor for efficiency. Why not just use the GMP version?

-
thank you for your feedback , here's the interesting bit, those long alphanumeric strings are actually very large prime numbers represented as hex values, the reason I put set_timelimit(0) was because BCMath is very very slow compared to GMP, I want to know if the BCMath implementation can be improved ... there are many question on StackOverflow saying that BCMath isn't as efficient as GMP for large mathematical calculations – cristi _b Dec 26 '12 at 19:09
regarding the speed issues, i once tested each action and/or method with microtime() on my usage scenario and bcmath operations took the longest ... – cristi _b Dec 26 '12 at 19:12
Oh, you know what... When I copied this over to my text editor to take a look at this I didn't notice that part of it got cut off. The GMP implementation that I saw only had the constructor, so I'll take another look at it in a few and get back to you. – mseancole Dec 26 '12 at 20:04
@cristi_b: Alright, post has been updated. – mseancole Dec 26 '12 at 21:51
i will rework my code then, your info is useful – cristi _b Dec 27 '12 at 5:37