public function atestDeterministicSign()
 {
     $f = file_get_contents(__DIR__ . '/../../data/rfc6979.json');
     $json = json_decode($f);
     $math = $this->math;
     $G = $this->G;
     foreach ($json->test as $test) {
         $G = CurveFactory::getGeneratorByName($test->curve);
         // Initialize private key and message hash (decimal)
         $privateKey = new PrivateKey($math, $G, $math->hexDec($test->privKey));
         $messageHash = $this->math->hexDec(hash($test->algorithm, $test->message));
         // Derive K
         $drbg = RandomGeneratorFactory::getHmacRandomGenerator($privateKey, $messageHash, $test->algorithm);
         // K must be correct (from privatekey and message hash)
         $k = $drbg->generate($G->getOrder());
         $this->assertEquals(strtolower($test->expectedK), $math->decHex($k));
         $hashBits = $this->math->baseConvert($messageHash, 10, 2);
         $size = NumberSize::bnNumBits($this->math, $messageHash);
         $messageHash = $this->math->baseConvert(substr($hashBits, 0, $size), 2, 10);
         $signer = new Signer($math);
         $sig = $signer->sign($privateKey, $messageHash, $k);
         // R and S should be correct
         $sR = $this->math->hexDec($test->expectedR);
         $sS = $this->math->hexDec($test->expectedS);
         $this->assertTrue($signer->verify($privateKey->getPublicKey(), $sig, $messageHash));
         $this->assertSame($sR, $sig->getR(), 'r');
         $this->assertSame($sS, $sig->getS(), 's');
     }
 }
Example #2
0
 /**
  * @param GeneratorPoint $G
  * @param $hash
  * @return int|string
  */
 public function truncateHash(GeneratorPoint $G, $hash)
 {
     $hexSize = strlen($this->adapter->decHex($hash));
     $hashBits = $this->adapter->baseConvert($hash, 10, 2);
     if (strlen($hashBits) < $hexSize * 4) {
         $hashBits = str_pad($hashBits, $hexSize * 4, '0', STR_PAD_LEFT);
     }
     $messageHash = $this->adapter->baseConvert(substr($hashBits, 0, NumberSize::bnNumBits($this->adapter, $G->getOrder())), 2, 10);
     return $messageHash;
 }
Example #3
0
 /**
  * @dataProvider getHmacTestSet
  * @param GeneratorPoint $G
  * @param integer $size
  * @param string $privKey
  * @param string $algo
  * @param string $message
  * @param string $eK expected K hex
  * @param string $eR expected R hex
  * @param string $eS expected S hex
  */
 public function testHmacSignatures(GeneratorPoint $G, $size, $privKey, $algo, $message, $eK, $eR, $eS)
 {
     //echo "Try {$test->curve} / {$test->algorithm} / '{$test->message}'\n";
     $math = $G->getAdapter();
     // Initialize private key and message hash (decimal)
     $privateKey = $G->getPrivateKeyFrom($math->hexDec($privKey));
     $hashHex = hash($algo, $message);
     $messageHash = $math->hexDec($hashHex);
     // Derive K
     $drbg = RandomGeneratorFactory::getHmacRandomGenerator($privateKey, $messageHash, $algo);
     $k = $drbg->generate($G->getOrder());
     $this->assertEquals($k, $math->hexdec($eK), 'k');
     $hexSize = strlen($hashHex);
     $hashBits = $math->baseConvert($messageHash, 10, 2);
     if (strlen($hashBits) < $hexSize * 4) {
         $hashBits = str_pad($hashBits, $hexSize * 4, '0', STR_PAD_LEFT);
     }
     $messageHash = $math->baseConvert(substr($hashBits, 0, NumberSize::bnNumBits($math, $G->getOrder())), 2, 10);
     $signer = new Signer($math);
     $sig = $signer->sign($privateKey, $messageHash, $k);
     // Should be consistent
     $this->assertTrue($signer->verify($privateKey->getPublicKey(), $sig, $messageHash));
     // R and S should be correct
     $sR = $math->hexDec($eR);
     $sS = $math->hexDec($eS);
     $this->assertSame($sR, $sig->getR(), "r {$sR} == " . $sig->getR());
     $this->assertSame($sS, $sig->getS(), "s {$sR} == " . $sig->getS());
 }
 /**
  * @dataProvider getBnNumBytesNumbers
  */
 public function testNumBytes(MathAdapterInterface $adapter, $number, $expected)
 {
     $size = NumberSize::bnNumBytes($adapter, $adapter->hexDec($number));
     $this->assertEquals($expected, $size);
 }
 /**
  * Generate a nonce based on the given $max
  *
  * {@inheritDoc}
  * @see \Mdanter\Ecc\Random\RandomNumberGeneratorInterface::generate()
  */
 public function generate($max)
 {
     if (is_null($this->result)) {
         $v = NumberSize::getCeiledByteSize($this->math, $max);
         while (true) {
             $hex = bin2hex($this->bytes($v));
             $rand = $this->math->hexDec($hex);
             // Check k is between [1, ... $max]
             if ($this->math->cmp(1, $rand) <= 0 && $this->math->cmp($rand, $max) < 0) {
                 break;
             }
             // Otherwise derive another and try again.
             $this->update(chr(0));
         }
         $this->result = $rand;
     }
     return $this->result;
 }
Example #6
0
 /**
  * @param int|string $integer
  * @param bool $fNegative
  * @return int|string
  */
 public function parseCompact($integer, $fNegative)
 {
     if (!is_bool($fNegative)) {
         throw new \InvalidArgumentException('CompactInteger::read() - flag must be boolean!');
     }
     $size = (int) NumberSize::bnNumBytes($this, $integer);
     if ($this->cmp($size, 3) <= 0) {
         $compact = $this->leftShift($this->getLow64($integer), $this->mul(8, $this->sub(3, $size)));
     } else {
         $compact = $this->rightShift($integer, $this->mul(8, $this->sub($size, 3)));
         $compact = $this->getLow64($compact);
     }
     if ($this->cmp($this->bitwiseAnd($compact, $this->hexDec('00800000')), 0) > 0) {
         $compact = $this->rightShift($compact, 8);
         $size++;
     }
     $compact = $this->bitwiseOr($compact, $this->leftShift($size, 24));
     if ($fNegative && $this->cmp($this->bitwiseAnd($compact, $this->hexDec('007fffff')), 0) > 0) {
         /// ?
         $compact = $this->bitwiseOr($compact, $this->hexDec('00800000'));
     }
     return $compact;
 }
Example #7
0
 /**
  * @dataProvider getByte
  */
 public function testGetFlooredByteSize(MathAdapterInterface $adapter, $x, $expected)
 {
     $size = NumberSize::getFlooredByteSize($adapter, $x);
     $this->assertEquals($expected, $size);
 }
 /**
  * @param int|string $max
  * @return int|string
  */
 public function generate($max)
 {
     $bytes = NumberSize::getFlooredByteSize($this->adapter, $max);
     $iv = mcrypt_create_iv($bytes, \MCRYPT_DEV_URANDOM);
     return $this->adapter->hexDec(bin2hex($iv));
 }