mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-19 21:55:15 +00:00
initial (wip) port of ldsignatures to jcseddsa2022, not yet ready for prime time
This commit is contained in:
parent
ee4837b0fb
commit
2cb5218e3b
2 changed files with 95 additions and 2 deletions
92
Code/Lib/JcsEddsa2022.php
Normal file
92
Code/Lib/JcsEddsa2022.php
Normal 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue