<?php
 declare(strict_types=1); namespace SpomkyLabs\Pki\CryptoTypes\Asymmetric\EC; use Brick\Math\BigInteger; use RangeException; use RuntimeException; use SpomkyLabs\Pki\ASN1\Type\Primitive\BitString; use SpomkyLabs\Pki\ASN1\Type\Primitive\Integer; use SpomkyLabs\Pki\ASN1\Type\Primitive\OctetString; use function mb_strlen; final class ECConversion { public static function bitStringToOctetString(BitString $bs): OctetString { $str = $bs->string(); if ($bs->unusedBits() !== 0) { throw new RuntimeException('Unaligned bitstrings to supported'); } return OctetString::create($str); } public static function octetStringToBitString(OctetString $os): BitString { return BitString::create($os->string()); } public static function integerToOctetString(Integer $num, ?int $mlen = null): OctetString { $bigInteger = BigInteger::of($num->getValue()); $str = $bigInteger->toBytes(false); if ($mlen !== null) { $len = mb_strlen($str, '8bit'); if ($len > $mlen) { throw new RangeException('Number is too large.'); } if ($len < $mlen) { $str = str_repeat("\0", $mlen - $len) . $str; } } return OctetString::create($str); } public static function octetStringToInteger(OctetString $os): Integer { $num = BigInteger::fromBytes($os->string(), false); return Integer::create($num); } public static function numberToOctets(int|string $num, ?int $mlen = null): string { return self::integerToOctetString(Integer::create($num), $mlen)->string(); } public static function octetsToNumber(string $str): string { return self::octetStringToInteger(OctetString::create($str))->number(); } } 