Skip to content

Commit ac395d4

Browse files
authored
Fix EdDSA algorithm (#168)
1 parent 8da90cc commit ac395d4

File tree

4 files changed

+14
-29
lines changed

4 files changed

+14
-29
lines changed

src/Component/Encryption/JWEDecrypter.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ private function checkCekSize(string $cek, KeyEncryptionAlgorithm $keyEncryption
156156
return;
157157
}
158158
if (mb_strlen($cek, '8bit') !== $algorithm->getCEKSize() / 8) {
159-
var_dump(mb_strlen($cek, '8bit'), $algorithm->getCEKSize() / 8);
160159
throw new \InvalidArgumentException('Invalid CEK size');
161160
}
162161
}

src/Component/KeyManagement/JWKFactory.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,27 +172,29 @@ public static function createOKPKey(string $curve, array $values = []): JWK
172172
switch ($curve) {
173173
case 'X25519':
174174
$keyPair = \sodium_crypto_box_keypair();
175-
$d = \sodium_crypto_box_secretkey($keyPair);
175+
$secret = \sodium_crypto_box_secretkey($keyPair);
176176
$x = \sodium_crypto_box_publickey($keyPair);
177177

178178
break;
179179
case 'Ed25519':
180180
$keyPair = \sodium_crypto_sign_keypair();
181-
$d = \sodium_crypto_sign_secretkey($keyPair);
181+
$secret = \sodium_crypto_sign_secretkey($keyPair);
182182
$x = \sodium_crypto_sign_publickey($keyPair);
183183

184184
break;
185185
default:
186186
throw new \InvalidArgumentException(\sprintf('Unsupported "%s" curve', $curve));
187187
}
188+
$secretLength = mb_strlen($secret, '8bit');
189+
$d = mb_substr($secret, 0, -$secretLength / 2, '8bit');
188190

189191
$values = \array_merge(
190192
$values,
191193
[
192194
'kty' => 'OKP',
193195
'crv' => $curve,
194-
'x' => Base64Url::encode($x),
195196
'd' => Base64Url::encode($d),
197+
'x' => Base64Url::encode($x),
196198
]
197199
);
198200

src/SignatureAlgorithm/EdDSA/EdDSA.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ public function sign(JWK $key, string $input): string
2929
if (!$key->has('d')) {
3030
throw new \InvalidArgumentException('The key is not private.');
3131
}
32-
$secret = Base64Url::decode($key->get('d'));
33-
$keyPair = \sodium_crypto_sign_seed_keypair($secret);
34-
$secretKey = \sodium_crypto_sign_secretkey($keyPair);
32+
$x = Base64Url::decode($key->get('x'));
33+
$d = Base64Url::decode($key->get('d'));
34+
$secret = $d.$x;
3535

3636
switch ($key->get('crv')) {
3737
case 'Ed25519':
38-
return \sodium_crypto_sign_detached($input, $secretKey);
38+
return \sodium_crypto_sign_detached($input, $secret);
3939
default:
4040
throw new \InvalidArgumentException('Unsupported curve');
4141
}
@@ -46,7 +46,6 @@ public function verify(JWK $key, string $input, string $signature): bool
4646
$this->checkKey($key);
4747

4848
$public = Base64Url::decode($key->get('x'));
49-
5049
switch ($key->get('crv')) {
5150
case 'Ed25519':
5251
return \sodium_crypto_sign_verify_detached($signature, $input, $public);

src/SignatureAlgorithm/EdDSA/Tests/EdDSASignatureTest.php

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@
1818
use Jose\Component\Core\Converter\StandardConverter;
1919
use Jose\Component\Core\JWK;
2020
use Jose\Component\Signature\Algorithm\EdDSA;
21-
use Jose\Component\Signature\JWS;
2221
use Jose\Component\Signature\JWSBuilder;
2322
use Jose\Component\Signature\JWSVerifier;
24-
use Jose\Component\Signature\Serializer\CompactSerializer;
2523
use PHPUnit\Framework\TestCase;
2624

2725
/**
@@ -31,7 +29,7 @@
3129
class EdDSASignatureTest extends TestCase
3230
{
3331
/**
34-
* @see https://tools.ietf.org/html/draft-ietf-jose-cfrg-curves-00#appendix-A.5
32+
* @see https://tools.ietf.org/html/rfc8037#appendix-A.5
3533
*
3634
* @test
3735
*/
@@ -48,13 +46,11 @@ public function edDSAVerifyAlgorithm()
4846
$input = 'eyJhbGciOiJFZERTQSJ9.RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc';
4947
$signature = Base64Url::decode('hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg');
5048

51-
$result = $eddsa->verify($key, $input, $signature);
52-
53-
static::assertTrue($result);
49+
static::assertTrue($eddsa->verify($key, $input, $signature));
5450
}
5551

5652
/**
57-
* @see https://tools.ietf.org/html/draft-ietf-jose-cfrg-curves-00#appendix-A.5
53+
* @see https://tools.ietf.org/html/rfc8037#appendix-A.5
5854
*
5955
* @test
6056
*/
@@ -68,7 +64,7 @@ public function edDSASignAndVerifyAlgorithm()
6864
]);
6965

7066
$header = ['alg' => 'EdDSA'];
71-
$input = Base64Url::decode('RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc');
67+
$input = 'Example of Ed25519 signing'; // Corresponds to "RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc"
7268

7369
$jwsBuilder = new JWSBuilder(
7470
new StandardConverter(),
@@ -77,22 +73,11 @@ public function edDSASignAndVerifyAlgorithm()
7773
$jwsVerifier = new JWSVerifier(
7874
AlgorithmManager::create([new EdDSA()])
7975
);
80-
$serializer = new CompactSerializer(
81-
new StandardConverter()
82-
);
8376
$jws = $jwsBuilder
8477
->create()->withPayload($input)
8578
->addSignature($key, $header)
8679
->build();
8780

88-
$jws = $serializer->serialize($jws, 0);
89-
90-
static::assertEquals('eyJhbGciOiJFZERTQSJ9.RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc.hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg', $jws);
91-
92-
$loaded = $serializer->unserialize($jws);
93-
94-
static::assertInstanceOf(JWS::class, $loaded);
95-
static::assertEquals(1, $loaded->countSignatures());
96-
static::assertTrue($jwsVerifier->verifyWithKey($loaded, $key, 0));
81+
static::assertTrue($jwsVerifier->verifyWithKey($jws, $key, 0));
9782
}
9883
}

0 commit comments

Comments
 (0)