1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#!/usr/bin/php
<?php
require "vendor/autoload.php";
use Mdanter\Ecc\Crypto\Signature\SignHasher;
use Mdanter\Ecc\Crypto\Key\PublicKey;
use Mdanter\Ecc\Primitives\Point;
use Mdanter\Ecc\EccFactory;
use Mdanter\Ecc\Crypto\Signature\Signer;
use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer;
use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer;
use Mdanter\Ecc\Math;
use Mdanter\Ecc\Math\GmpMath;
// ECDSA domain is defined by curve/generator/hash algorithm,
// which a verifier must be aware of.
$adapter = EccFactory::getAdapter();
$generator = EccFactory::getNistCurves()->generator384();
$useDerandomizedSignatures = true;
$algorithm = 'sha384';
$derSerializer = new DerPrivateKeySerializer($adapter);
## generate der key
$private = $generator->createPrivateKey();
echo "privkey: " . $private->getSecret() . PHP_EOL;
$der = $derSerializer->serialize($private);
$math = new GmpMath();
// echo bin2hex($math->intToString($private->getSecret())) . PHP_EOL;
// echo bin2hex($der) . PHP_EOL;
## You'll be restoring from a key, as opposed to generating one.
$key = $derSerializer->parse($der);
$document = 'I am writing today...';
$hasher = new SignHasher($algorithm, $adapter);
$hash = $hasher->makeHash($document, $generator);
echo "message: $document" . PHP_EOL;
echo "hash: $hash" . PHP_EOL;
# Derandomized signatures are not necessary, but is avoids
# the risk of a low entropy RNG, causing accidental reuse
# of a k value for a different message, which leaks the
# private key.
if ($useDerandomizedSignatures) {
$random = \Mdanter\Ecc\Random\RandomGeneratorFactory::getHmacRandomGenerator($key, $hash, $algorithm);
} else {
$random = \Mdanter\Ecc\Random\RandomGeneratorFactory::getRandomGenerator();
}
$randomK = $random->generate($generator->getOrder());
$signer = new Signer($adapter);
$signature = $signer->sign($key, $hash, $randomK);
# $serializer = new DerSignatureSerializer();
# $serializedSig = $serializer->serialize($signature);
# echo base64_encode($serializedSig) . PHP_EOL;
echo "signature: r=" . $signature->getR() . " s=" . $signature->getS() . PHP_EOL;
$pubkey = $key->getPublicKey();
$x = $pubkey->getPoint()->getX();
$y = $pubkey->getPoint()->getY();
echo "public key: x=" . $x . " y=" . $y . PHP_EOL;
$publickey = new PublicKey($adapter, $generator, new Point($adapter, EccFactory::getNistCurves()->curve384(), $x, $y));
echo "signature check " . ($signer->verify($publickey, $signature, $hash) ? "passed" : "failed") . PHP_EOL;
|