mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 13:47:46 +00:00
LibCrypto+LibTLS: Generalize the elliptic curve interface
These changes generalize the interface with an elliptic curve implementation. This allows LibTLS to support elliptic curves generally without needing the specifics of elliptic curve implementations. This should allow for easier addition of other elliptic curves.
This commit is contained in:
parent
21bbff0349
commit
c1b041e761
10 changed files with 133 additions and 122 deletions
24
Userland/Libraries/LibCrypto/Curves/EllipticCurve.h
Normal file
24
Userland/Libraries/LibCrypto/Curves/EllipticCurve.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Michiel Visser <opensource@webmichiel.nl>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
|
||||
namespace Crypto::Curves {
|
||||
|
||||
class EllipticCurve {
|
||||
public:
|
||||
virtual size_t key_size() = 0;
|
||||
virtual ErrorOr<ByteBuffer> generate_private_key() = 0;
|
||||
virtual ErrorOr<ByteBuffer> generate_public_key(ReadonlyBytes a) = 0;
|
||||
virtual ErrorOr<ByteBuffer> compute_coordinate(ReadonlyBytes scalar_bytes, ReadonlyBytes point_bytes) = 0;
|
||||
virtual ErrorOr<ByteBuffer> derive_premaster_key(ReadonlyBytes shared_point) = 0;
|
||||
|
||||
virtual ~EllipticCurve() = default;
|
||||
};
|
||||
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <AK/ByteReader.h>
|
||||
#include <AK/Endian.h>
|
||||
#include <AK/Random.h>
|
||||
#include <LibCrypto/Curves/X25519.h>
|
||||
|
||||
namespace Crypto::Curves {
|
||||
|
@ -259,6 +260,19 @@ void X25519::modular_multiply_inverse(u32* state, u32* value)
|
|||
modular_multiply(state, u, value);
|
||||
}
|
||||
|
||||
ErrorOr<ByteBuffer> X25519::generate_private_key()
|
||||
{
|
||||
auto buffer = TRY(ByteBuffer::create_uninitialized(BYTES));
|
||||
fill_with_random(buffer.data(), buffer.size());
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ErrorOr<ByteBuffer> X25519::generate_public_key(ReadonlyBytes a)
|
||||
{
|
||||
u8 generator[BYTES] { 9 };
|
||||
return compute_coordinate(a, { generator, BYTES });
|
||||
}
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc7748#section-5
|
||||
ErrorOr<ByteBuffer> X25519::compute_coordinate(ReadonlyBytes input_k, ReadonlyBytes input_u)
|
||||
{
|
||||
|
@ -334,4 +348,12 @@ ErrorOr<ByteBuffer> X25519::compute_coordinate(ReadonlyBytes input_k, ReadonlyBy
|
|||
// Encode state for export
|
||||
return export_state(u);
|
||||
}
|
||||
|
||||
ErrorOr<ByteBuffer> X25519::derive_premaster_key(ReadonlyBytes shared_point)
|
||||
{
|
||||
VERIFY(shared_point.size() == BYTES);
|
||||
ByteBuffer premaster_key = TRY(ByteBuffer::copy(shared_point));
|
||||
return premaster_key;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <LibCrypto/Curves/EllipticCurve.h>
|
||||
|
||||
namespace Crypto::Curves {
|
||||
|
||||
class X25519 {
|
||||
class X25519 : public EllipticCurve {
|
||||
|
||||
static constexpr u8 BITS = 255;
|
||||
static constexpr u8 BYTES = 32;
|
||||
|
@ -18,7 +19,11 @@ class X25519 {
|
|||
static constexpr u32 A24 = 121666;
|
||||
|
||||
public:
|
||||
static ErrorOr<ByteBuffer> compute_coordinate(ReadonlyBytes a, ReadonlyBytes b);
|
||||
size_t key_size() override { return BYTES; }
|
||||
ErrorOr<ByteBuffer> generate_private_key() override;
|
||||
ErrorOr<ByteBuffer> generate_public_key(ReadonlyBytes a) override;
|
||||
ErrorOr<ByteBuffer> compute_coordinate(ReadonlyBytes a, ReadonlyBytes b) override;
|
||||
ErrorOr<ByteBuffer> derive_premaster_key(ReadonlyBytes shared_point) override;
|
||||
|
||||
private:
|
||||
static void import_state(u32* state, ReadonlyBytes data);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <AK/ByteReader.h>
|
||||
#include <AK/Endian.h>
|
||||
#include <AK/Random.h>
|
||||
#include <LibCrypto/Curves/X448.h>
|
||||
|
||||
namespace Crypto::Curves {
|
||||
|
@ -282,6 +283,19 @@ void X448::modular_multiply_inverse(u32* state, u32* value)
|
|||
modular_multiply(state, u, value);
|
||||
}
|
||||
|
||||
ErrorOr<ByteBuffer> X448::generate_private_key()
|
||||
{
|
||||
auto buffer = TRY(ByteBuffer::create_uninitialized(BYTES));
|
||||
fill_with_random(buffer.data(), buffer.size());
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ErrorOr<ByteBuffer> X448::generate_public_key(ReadonlyBytes a)
|
||||
{
|
||||
u8 generator[BYTES] { 5 };
|
||||
return compute_coordinate(a, { generator, BYTES });
|
||||
}
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc7748#section-5
|
||||
ErrorOr<ByteBuffer> X448::compute_coordinate(ReadonlyBytes input_k, ReadonlyBytes input_u)
|
||||
{
|
||||
|
@ -353,4 +367,12 @@ ErrorOr<ByteBuffer> X448::compute_coordinate(ReadonlyBytes input_k, ReadonlyByte
|
|||
// Encode state for export
|
||||
return export_state(u);
|
||||
}
|
||||
|
||||
ErrorOr<ByteBuffer> X448::derive_premaster_key(ReadonlyBytes shared_point)
|
||||
{
|
||||
VERIFY(shared_point.size() == BYTES);
|
||||
ByteBuffer premaster_key = TRY(ByteBuffer::copy(shared_point));
|
||||
return premaster_key;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <LibCrypto/Curves/EllipticCurve.h>
|
||||
|
||||
namespace Crypto::Curves {
|
||||
|
||||
class X448 {
|
||||
class X448 : public EllipticCurve {
|
||||
|
||||
static constexpr u16 BITS = 448;
|
||||
static constexpr u8 BYTES = 56;
|
||||
|
@ -18,7 +19,11 @@ class X448 {
|
|||
static constexpr u32 A24 = 39082;
|
||||
|
||||
public:
|
||||
static ErrorOr<ByteBuffer> compute_coordinate(ReadonlyBytes a, ReadonlyBytes b);
|
||||
size_t key_size() override { return BYTES; }
|
||||
ErrorOr<ByteBuffer> generate_private_key() override;
|
||||
ErrorOr<ByteBuffer> generate_public_key(ReadonlyBytes a) override;
|
||||
ErrorOr<ByteBuffer> compute_coordinate(ReadonlyBytes a, ReadonlyBytes b) override;
|
||||
ErrorOr<ByteBuffer> derive_premaster_key(ReadonlyBytes shared_point) override;
|
||||
|
||||
private:
|
||||
static void import_state(u32* state, ReadonlyBytes data);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue