Skip to content

Commit 9bc4c64

Browse files
committed
add support for brainpoolP256r1
1 parent 76b5184 commit 9bc4c64

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

src/Library/Core/Util/ECKey.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public static function convertPublicKeyToPEM(JWK $jwk): string
3232
{
3333
$der = match ($jwk->get('crv')) {
3434
'P-256' => self::p256PublicKey(),
35+
'BP-256' => self::p256PublicKey(),
3536
'secp256k1' => self::p256KPublicKey(),
3637
'P-384' => self::p384PublicKey(),
3738
'P-521' => self::p521PublicKey(),
@@ -48,6 +49,7 @@ public static function convertPrivateKeyToPEM(JWK $jwk): string
4849
{
4950
$der = match ($jwk->get('crv')) {
5051
'P-256' => self::p256PrivateKey($jwk),
52+
'BP-256' => self::p256PrivateKey($jwk),
5153
'secp256k1' => self::p256KPrivateKey($jwk),
5254
'P-384' => self::p384PrivateKey($jwk),
5355
'P-521' => self::p521PrivateKey($jwk),
@@ -77,7 +79,7 @@ public static function createECKey(string $curve, array $values = []): JWK
7779
private static function getNistCurveSize(string $curve): int
7880
{
7981
return match ($curve) {
80-
'P-256', 'secp256k1' => 256,
82+
'P-256', 'BP-256', 'secp256k1' => 256,
8183
'P-384' => 384,
8284
'P-521' => 521,
8385
default => throw new InvalidArgumentException(sprintf('The curve "%s" is not supported.', $curve)),
@@ -130,6 +132,7 @@ private static function getOpensslCurveName(string $curve): string
130132
{
131133
return match ($curve) {
132134
'P-256' => 'prime256v1',
135+
'BP-256' => 'brainpoolP256r1',
133136
'secp256k1' => 'secp256k1',
134137
'P-384' => 'secp384r1',
135138
'P-521' => 'secp521r1',
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Jose\Component\Core\Util\Ecc;
6+
7+
use Brick\Math\BigInteger;
8+
9+
/**
10+
* Copyright (C) 2024 Robert Böser.
11+
*
12+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13+
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
14+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
15+
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
18+
* Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
21+
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
22+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
26+
/**
27+
* @internal
28+
*/
29+
final class BrainpoolCurve
30+
{
31+
/**
32+
* Returns an Brainpool BP-256 curve.
33+
* RFC 5639 - brainpoolP256r1
34+
*/
35+
public static function curve256(): Curve
36+
{
37+
$p = BigInteger::fromBase('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16);
38+
$a = BigInteger::fromBase('7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9', 16);
39+
$b = BigInteger::fromBase('26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6', 16);
40+
$x = BigInteger::fromBase('8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262', 16);
41+
$y = BigInteger::fromBase('547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997', 16);
42+
$n = BigInteger::fromBase('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16);
43+
$generator = Point::create($x, $y, $n);
44+
45+
return new Curve(256, $p, $a, $b, $generator);
46+
}
47+
48+
}

src/Library/Encryption/Algorithm/KeyEncryption/AbstractECDH.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Jose\Component\Core\Util\Ecc\Curve;
1212
use Jose\Component\Core\Util\Ecc\EcDH;
1313
use Jose\Component\Core\Util\Ecc\NistCurve;
14+
use Jose\Component\Core\Util\Ecc\BrainpoolCurve;
1415
use Jose\Component\Core\Util\Ecc\PrivateKey;
1516
use Jose\Component\Core\Util\ECKey;
1617
use Jose\Component\Encryption\Algorithm\KeyEncryption\Util\ConcatKDF;
@@ -83,6 +84,7 @@ protected function calculateAgreementKey(JWK $private_key, JWK $public_key): str
8384
case 'P-256':
8485
case 'P-384':
8586
case 'P-521':
87+
case 'BP-256':
8688
$curve = $this->getCurve($crv);
8789
if (function_exists('openssl_pkey_derive')) {
8890
try {
@@ -158,7 +160,7 @@ protected function getKeysFromPublicKey(
158160
throw new InvalidArgumentException('Invalid key parameter "crv"');
159161
}
160162
$private_key = match ($crv) {
161-
'P-256', 'P-384', 'P-521' => $senderKey ?? ECKey::createECKey($crv),
163+
'P-256', 'P-384', 'P-521', 'BP-256' => $senderKey ?? ECKey::createECKey($crv),
162164
'X25519' => $senderKey ?? $this->createOKPKey('X25519'),
163165
default => throw new InvalidArgumentException(sprintf('The curve "%s" is not supported', $crv)),
164166
};
@@ -221,6 +223,7 @@ private function checkKey(JWK $key, bool $is_private): void
221223
case 'P-256':
222224
case 'P-384':
223225
case 'P-521':
226+
case 'BP-256':
224227
if (! $key->has('y')) {
225228
throw new InvalidArgumentException('The key parameter "y" is missing.');
226229
}
@@ -244,6 +247,7 @@ private function getCurve(string $crv): Curve
244247
'P-256' => NistCurve::curve256(),
245248
'P-384' => NistCurve::curve384(),
246249
'P-521' => NistCurve::curve521(),
250+
'BP-256' => BrainpoolCurve::curve256(),
247251
default => throw new InvalidArgumentException(sprintf('The curve "%s" is not supported', $crv)),
248252
};
249253
}

0 commit comments

Comments
 (0)