protected function calculateRoot() : string
{
$size = \count($this->nodes);
if ($size < 1) {
return '';
}
$order = self::getSizeRoundedUp($size);
$hash = [];
// Population (Use self::MERKLE_LEAF as a prefix)
for ($i = 0; $i < $order; ++$i) {
if ($i >= $size) {
$hash[$i] = self::MERKLE_LEAF . $this->personalization . $this->nodes[$size - 1]->getHash(true, $this->outputSize, $this->personalization);
} else {
$hash[$i] = self::MERKLE_LEAF . $this->personalization . $this->nodes[$i]->getHash(true, $this->outputSize, $this->personalization);
}
}
// Calculation (Use self::MERKLE_BRANCH as a prefix)
do {
$tmp = [];
$j = 0;
for ($i = 0; $i < $order; $i += 2) {
if (empty($hash[$i + 1])) {
$tmp[$j] = Util::raw_hash(self::MERKLE_BRANCH . $this->personalization . $hash[$i] . $hash[$i], $this->outputSize);
} else {
$tmp[$j] = Util::raw_hash(self::MERKLE_BRANCH . $this->personalization . $hash[$i] . $hash[$i + 1], $this->outputSize);
}
++$j;
}
$hash = $tmp;
$order >>= 1;
} while ($order > 1);
// We should only have one value left:t
$this->rootCalculated = true;
return \array_shift($hash);
}