initial (wip) port of ldsignatures to jcseddsa2022, not yet ready for prime time

This commit is contained in:
Mike Macgirvin 2024-01-01 21:13:27 +11:00
parent ee4837b0fb
commit 2cb5218e3b
2 changed files with 95 additions and 2 deletions

92
Code/Lib/JcsEddsa2022.php Normal file
View file

@ -0,0 +1,92 @@
<?php
namespace Code\Lib;
use Mmccook\JsonCanonicalizator\JsonCanonicalizatorFactory;
use Mmccook\JsonCanonicalizator\JsonCanonicalizator;
use Mmccook\JsonCanonicalizator\JsonCanonicalizatorInterface;
use Code\Lib\Multibase;
class JcsEddsa2022
{
public function __construct()
{
return $this;
}
public function sign($data, $channel): array
{
$options = [
'type' => 'RsaSignature2017',
'nonce' => random_string(),
'creator' => Channel::url($channel),
'created' => datetime_convert('UTC', 'UTC', 'now', 'Y-m-d\TH:i:s\Z')
];
$binaryKey = sodium_base642bin($channel['channel_eprvkey'], SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING);
$ohash = $this->hash($this->signable_options($options));
$dhash = $this->hash($this->signable_data($data));
$options['signatureValue'] = base64_encode(Crypto::sign($ohash . $dhash, $binaryKey));
return $options;
}
public function verify($data, $publicKey)
{
$ohash = $this->hash($this->signable_options($data['signature']));
$dhash = $this->hash($this->signable_data($data));
$binaryKey = (new Multibase())->decode($publicKey, true);
$result = false;
if (!empty($data['signature']['signatureValue'])) {
$result = Crypto::verify($ohash . $dhash, base64_decode($data['signature']['signatureValue']), $pubkey);
logger('JcsEdddsa2022: ' . ((intval($result)) ? 'true' : 'false'));
}
return $result;
}
public function signable_data($data): bool|string
{
$newdata = [];
if ($data) {
foreach ($data as $k => $v) {
if ($k != 'signature') {
$newdata[$k] = $v;
}
}
}
return json_encode($newdata, JSON_UNESCAPED_SLASHES);
}
public function signable_options($options): bool|string
{
$newopts = ['@context' => 'https://w3id.org/identity/v1'];
if ($options) {
foreach ($options as $k => $v) {
if (!in_array($k, ['type', 'id', 'signatureValue'])) {
$newopts[$k] = $v;
}
}
}
return json_encode($newopts, JSON_UNESCAPED_SLASHES);
}
public function hash($obj): string
{
return hash('sha256', $this->canonicalize($obj));
}
public function canonicalize($data)
{
$canonicalization = JsonCanonicalizatorFactory::getInstance();
return $canonicalization->canonicalize($data);
}
}

View file

@ -27,12 +27,13 @@ class Multibase
return 'z' . $base58->encode($raw);
}
public function decode($key)
public function decode($key, $binary = false)
{
$base58 = new Base58();
$key = substr($key,1);
$raw = $base58->decode($key);
return sodium_bin2base64(substr($raw, 2), SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING);
$binaryKey = substr($raw, 2);
return $binary ? $binaryKey : sodium_bin2base64($binaryKey, SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING);
}
}