예제 #1
1
 /**
  * @param \ParagonIE\AsgardClient\Structures\MerkleTree $tree
  * @param string $prevhash
  * @param string $nexthash
  */
 public function __construct(MerkleTree $tree, $prevhash = null, $nexthash = null)
 {
     $this->merkleTree = $tree;
     $this->currentHash = $tree->getRoot();
     $this->previousHash = $prevhash;
     $this->nextHash = $nexthash;
     if (empty($prevhash)) {
         $this->tailHash = $this->currentHash;
     } else {
         $this->tailHash = \Sodium::crypto_generichash(\bin2hex($this->previousHash) . \bin2hex($this->currentHash));
     }
 }
예제 #2
0
 /**
  * Verify the checksums on $tmp_file for the package we are verifying
  * 
  * @param array $blockdata
  * @param string $tmp_file
  * @return boolean
  */
 private function verifyChecksums($blockdata, $tmp_file)
 {
     $matches = 0;
     $filedata = \file_get_contents($tmp_file);
     // Now let's check all of the hashes
     foreach ($blockdata['checksums'] as $algo => $hash) {
         switch ($algo) {
             case 'BLAKE2b':
                 // We used libsodium
                 $line = \Sodium::crypto_generichash($filedata);
                 break;
             default:
                 // A simple hash (SHA256, etc)
                 $line = \hash($algo, $filedata, true);
         }
         if (\hash_equals($line, \Sodium::sodium_hex2bin($hash))) {
             ++$matches;
         } else {
             die("{$algo} hash did not match!");
         }
     }
     unset($filedata);
     // explicitly free
     return $matches > 0;
 }
예제 #3
0
 /**
  * Calculate the hash tree for a given dataset:
  *     0 => Merkle Root
  *     1 => Left Child
  *     2 => Right Child,
  *     3 => LL, 4 => LR
  *     5 => RL, 6 => RR,
  *     ...
  * 
  * @return array
  */
 public function getTree()
 {
     $numLeaves = count($this->leaves);
     // get the next 2^N larger than our dataset
     $baseIterate = (int) pow(2, ceil(log($numLeaves, 2)));
     $hashes = [];
     // Initial population
     for ($i = 0; $i < $baseIterate; ++$i) {
         if ($i >= $numLeaves) {
             // Following Bitcoin's lead; keep hashing the remainder
             $hashes[] = $this->leaves[$numLeaves - 1]['hash'];
         } else {
             $hashes[] = $this->leaves[$i]['hash'];
         }
     }
     $tree = $hashes;
     // Let's hash together until we have one node left
     do {
         $tmp = [];
         // Iterate through the first level of the tree
         $j = 0;
         for ($i = 0; $i < $baseIterate; $i += 2) {
             $tmp[$j] = \Sodium::crypto_generichash($hashes[$i] . $hashes[$i + 1]);
             \array_unshift($tree, $tmp[$j]);
             ++$j;
         }
         $hashes = $tmp;
         $baseIterate = $baseIterate >> 1;
     } while ($baseIterate > 1);
     return $tree;
 }