mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-04 10:45:50 +00:00
Compare commits
1 Commits
sublimator
...
dilithium
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef800d7038 |
@@ -153,6 +153,7 @@ target_link_libraries (xrpl_core
|
||||
Ripple::syslibs
|
||||
secp256k1::secp256k1
|
||||
ed25519::ed25519
|
||||
NIH::dilithium2_ref
|
||||
date::date
|
||||
Ripple::opts)
|
||||
#[=================================[
|
||||
|
||||
84
Builds/CMake/deps/dilithium.cmake
Normal file
84
Builds/CMake/deps/dilithium.cmake
Normal file
@@ -0,0 +1,84 @@
|
||||
include(FetchContent)
|
||||
|
||||
ExternalProject_Add(
|
||||
dilithium_src
|
||||
PREFIX ${nih_cache_path}
|
||||
GIT_REPOSITORY https://github.com/pq-crystals/dilithium.git
|
||||
GIT_TAG v3.1
|
||||
CMAKE_ARGS
|
||||
-DDILITHIUM_MODE=2
|
||||
-DDILITHIUM_RANDOMIZED_SIGNING=ON
|
||||
-DDILITHIUM_USE_AES=ON
|
||||
LOG_BUILD ON
|
||||
LOG_CONFIGURE ON
|
||||
COMMAND
|
||||
pwd
|
||||
BUILD_COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
--build .
|
||||
--config $<CONFIG>
|
||||
$<$<VERSION_GREATER_EQUAL:${CMAKE_VERSION},3.12>:--parallel ${ep_procs}>
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_BYPRODUCTS
|
||||
<BINARY_DIR>/ref/libdilithium2_ref.a
|
||||
<BINARY_DIR>/ref/libdilithium2aes_ref.a
|
||||
<BINARY_DIR>/ref/libfips202_ref.a
|
||||
)
|
||||
|
||||
ExternalProject_Get_Property(dilithium_src BINARY_DIR)
|
||||
ExternalProject_Get_Property(dilithium_src SOURCE_DIR)
|
||||
set(dilithium_src_SOURCE_DIR "${SOURCE_DIR}")
|
||||
set(dilithium_src_BINARY_DIR "${BINARY_DIR}")
|
||||
|
||||
# Check if the api.h file exists
|
||||
include_directories("${dilithium_src_SOURCE_DIR}/ref")
|
||||
|
||||
# Create imported targets for each static library
|
||||
add_library(dilithium::dilithium2_ref STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(dilithium::dilithium2_ref PROPERTIES
|
||||
IMPORTED_LOCATION "${dilithium_src_BINARY_DIR}/ref/libdilithium2_ref.a"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${dilithium_src_SOURCE_DIR}/ref/"
|
||||
)
|
||||
|
||||
add_library(dilithium::dilithium2aes_ref STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(dilithium::dilithium2aes_ref PROPERTIES
|
||||
IMPORTED_LOCATION "${dilithium_src_BINARY_DIR}/ref/libdilithium2aes_ref.a"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${dilithium_src_SOURCE_DIR}/ref/"
|
||||
)
|
||||
|
||||
add_library(dilithium::libfips202_ref STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(dilithium::libfips202_ref PROPERTIES
|
||||
IMPORTED_LOCATION "${dilithium_src_BINARY_DIR}/ref/libfips202_ref.a"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${dilithium_src_SOURCE_DIR}/ref/"
|
||||
)
|
||||
|
||||
add_dependencies(dilithium::dilithium2_ref dilithium_src)
|
||||
add_dependencies(dilithium::dilithium2aes_ref dilithium_src)
|
||||
add_dependencies(dilithium::libfips202_ref dilithium_src)
|
||||
|
||||
# Add a custom command to generate randombytes.c
|
||||
add_custom_command(
|
||||
OUTPUT "${dilithium_src_BINARY_DIR}/ref/randombytes.c"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${dilithium_src_SOURCE_DIR}/ref/randombytes.c" "${dilithium_src_BINARY_DIR}/ref/randombytes.c"
|
||||
DEPENDS dilithium_src
|
||||
)
|
||||
|
||||
# Add the randombytes_ref library
|
||||
add_library(randombytes_ref STATIC "${dilithium_src_BINARY_DIR}/ref/randombytes.c")
|
||||
|
||||
# Include the Dilithium ref directory for headers
|
||||
target_include_directories(randombytes_ref PUBLIC "${dilithium_src_SOURCE_DIR}/ref")
|
||||
|
||||
# Ensure that randombytes_ref depends on the Dilithium source so it's built after
|
||||
add_dependencies(randombytes_ref dilithium_src)
|
||||
|
||||
# Create an interface library that links to both
|
||||
target_link_libraries(ripple_libs INTERFACE
|
||||
randombytes_ref
|
||||
dilithium::dilithium2_ref
|
||||
dilithium::dilithium2aes_ref
|
||||
dilithium::libfips202_ref
|
||||
)
|
||||
|
||||
# Link the Dilithium library to your target
|
||||
add_library(NIH::dilithium2_ref ALIAS dilithium::dilithium2_ref)
|
||||
@@ -81,6 +81,7 @@ endif ()
|
||||
include(RippledCompiler)
|
||||
include(RippledInterface)
|
||||
|
||||
include(deps/dilithium)
|
||||
###
|
||||
if (NOT USE_CONAN)
|
||||
add_subdirectory(src/secp256k1)
|
||||
|
||||
@@ -587,6 +587,23 @@ SetAccount::doApply()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// QuantumSignature
|
||||
//
|
||||
if (ctx_.view().rules().enabled(featureQuantumSigning))
|
||||
{
|
||||
if (uSetFlag == asfForceQuantum)
|
||||
{
|
||||
JLOG(j_.trace()) << "Set lsfForceQuantum.";
|
||||
uFlagsOut |= lsfForceQuantum;
|
||||
}
|
||||
else if (uClearFlag == asfForceQuantum)
|
||||
{
|
||||
JLOG(j_.trace()) << "Clear lsfForceQuantum.";
|
||||
uFlagsOut &= ~lsfForceQuantum;
|
||||
}
|
||||
}
|
||||
|
||||
if (uFlagsIn != uFlagsOut)
|
||||
sle->setFieldU32(sfFlags, uFlagsOut);
|
||||
|
||||
|
||||
@@ -40,6 +40,13 @@
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
#include <limits>
|
||||
#include <set>
|
||||
extern "C" {
|
||||
#include "api.h"
|
||||
}
|
||||
|
||||
#ifndef DILITHIUM_PK_SIZE
|
||||
#define DILITHIUM_PK_SIZE pqcrystals_dilithium2_PUBLICKEYBYTES
|
||||
#endif
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -857,13 +864,18 @@ Transactor::checkSingleSign(PreclaimContext const& ctx)
|
||||
}
|
||||
|
||||
// Look up the account.
|
||||
auto const idSigner = calcAccountID(PublicKey(makeSlice(pkSigner)));
|
||||
PublicKey pubKey = PublicKey(makeSlice(pkSigner));
|
||||
auto const idSigner = calcAccountID(pubKey);
|
||||
auto const idAccount = ctx.tx.getAccountID(sfAccount);
|
||||
auto const sleAccount = ctx.view.read(keylet::account(idAccount));
|
||||
|
||||
if (!sleAccount)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
if (ctx.view.rules().enabled(featureQuantumSigning) &&
|
||||
sleAccount->isFlag(lsfForceQuantum) && pubKey.size() != DILITHIUM_PK_SIZE)
|
||||
return telBAD_PUBLIC_KEY;
|
||||
|
||||
bool const isMasterDisabled = sleAccount->isFlag(lsfDisableMaster);
|
||||
|
||||
if (ctx.view.rules().enabled(fixMasterKeyAsRegularKey))
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace detail {
|
||||
// Feature.cpp. Because it's only used to reserve storage, and determine how
|
||||
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
|
||||
// the actual number of amendments. A LogicError on startup will verify this.
|
||||
static constexpr std::size_t numFeatures = 81;
|
||||
static constexpr std::size_t numFeatures = 82;
|
||||
|
||||
/** Amendments that this server supports and the default voting behavior.
|
||||
Whether they are enabled depends on the Rules defined in the validated
|
||||
@@ -369,6 +369,7 @@ extern uint256 const fixXahauV3;
|
||||
extern uint256 const fix20250131;
|
||||
extern uint256 const featureHookCanEmit;
|
||||
extern uint256 const fixRewardClaimFlags;
|
||||
extern uint256 const featureQuantumSigning;
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace ripple {
|
||||
enum class KeyType {
|
||||
secp256k1 = 0,
|
||||
ed25519 = 1,
|
||||
dilithium = 2,
|
||||
};
|
||||
|
||||
inline std::optional<KeyType>
|
||||
@@ -39,6 +40,9 @@ keyTypeFromString(std::string const& s)
|
||||
if (s == "ed25519")
|
||||
return KeyType::ed25519;
|
||||
|
||||
if (s == "dilithium")
|
||||
return KeyType::dilithium;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -50,6 +54,9 @@ to_string(KeyType type)
|
||||
|
||||
if (type == KeyType::ed25519)
|
||||
return "ed25519";
|
||||
|
||||
if (type == KeyType::dilithium)
|
||||
return "dilithium";
|
||||
|
||||
return "INVALID";
|
||||
}
|
||||
|
||||
@@ -275,6 +275,7 @@ enum LedgerSpecificFlags {
|
||||
0x00800000, // True, trust lines allow rippling by default
|
||||
lsfDepositAuth = 0x01000000, // True, all deposits require authorization
|
||||
lsfTshCollect = 0x02000000, // True, allow TSH collect-calls to acc hooks
|
||||
lsfForceQuantum = 0x04000000, // True, force quantum-resistant signature
|
||||
lsfDisallowIncomingNFTokenOffer =
|
||||
0x04000000, // True, reject new incoming NFT offers
|
||||
lsfDisallowIncomingCheck =
|
||||
|
||||
@@ -43,10 +43,11 @@ namespace ripple {
|
||||
information needed to determine the cryptosystem
|
||||
parameters used is stored inside the key.
|
||||
|
||||
As of this writing two systems are supported:
|
||||
As of this writing three systems are supported:
|
||||
|
||||
secp256k1
|
||||
ed25519
|
||||
dilithium
|
||||
|
||||
secp256k1 public keys consist of a 33 byte
|
||||
compressed public key, with the lead byte equal
|
||||
@@ -55,12 +56,14 @@ namespace ripple {
|
||||
The ed25519 public keys consist of a 1 byte
|
||||
prefix constant 0xED, followed by 32 bytes of
|
||||
public key data.
|
||||
|
||||
The dilithium public keys will have their own specific format.
|
||||
*/
|
||||
class PublicKey
|
||||
{
|
||||
protected:
|
||||
std::uint8_t buf_[1312];
|
||||
std::size_t size_ = 0;
|
||||
std::uint8_t buf_[33]; // should be large enough
|
||||
|
||||
public:
|
||||
using const_iterator = std::uint8_t const*;
|
||||
|
||||
@@ -36,7 +36,8 @@ namespace ripple {
|
||||
class SecretKey
|
||||
{
|
||||
private:
|
||||
std::uint8_t buf_[32];
|
||||
std::uint8_t buf_[2528];
|
||||
std::size_t size_ = 0;
|
||||
|
||||
public:
|
||||
using const_iterator = std::uint8_t const*;
|
||||
@@ -49,6 +50,7 @@ public:
|
||||
~SecretKey();
|
||||
|
||||
SecretKey(std::array<std::uint8_t, 32> const& data);
|
||||
SecretKey(std::array<std::uint8_t, 2528> const& data);
|
||||
SecretKey(Slice const& slice);
|
||||
|
||||
std::uint8_t const*
|
||||
@@ -60,7 +62,7 @@ public:
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
return sizeof(buf_);
|
||||
return size_;
|
||||
}
|
||||
|
||||
/** Convert the secret key to a hexadecimal string.
|
||||
@@ -86,13 +88,13 @@ public:
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return buf_ + sizeof(buf_);
|
||||
return buf_ + size_;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{
|
||||
return buf_ + sizeof(buf_);
|
||||
return buf_ + size_;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -126,6 +128,10 @@ toBase58(TokenType type, SecretKey const& sk)
|
||||
SecretKey
|
||||
randomSecretKey();
|
||||
|
||||
/** Create a secret key using secure random numbers. */
|
||||
SecretKey
|
||||
randomSecretKey(KeyType type);
|
||||
|
||||
/** Generate a new secret key deterministically. */
|
||||
SecretKey
|
||||
generateSecretKey(KeyType type, Seed const& seed);
|
||||
|
||||
@@ -92,6 +92,7 @@ enum AccountFlags : uint32_t {
|
||||
asfDisallowIncomingPayChan = 14,
|
||||
asfDisallowIncomingTrustline = 15,
|
||||
asfDisallowIncomingRemit = 16,
|
||||
asfForceQuantum = 17,
|
||||
};
|
||||
|
||||
// OfferCreate flags:
|
||||
|
||||
@@ -475,6 +475,7 @@ REGISTER_FIX (fixXahauV3, Supported::yes, VoteBehavior::De
|
||||
REGISTER_FIX (fix20250131, Supported::yes, VoteBehavior::DefaultYes);
|
||||
REGISTER_FEATURE(HookCanEmit, Supported::yes, VoteBehavior::DefaultNo);
|
||||
REGISTER_FIX (fixRewardClaimFlags, Supported::yes, VoteBehavior::DefaultYes);
|
||||
REGISTER_FEATURE(QuantumSigning, Supported::yes, VoteBehavior::DefaultYes);
|
||||
|
||||
// The following amendments are obsolete, but must remain supported
|
||||
// because they could potentially get enabled.
|
||||
|
||||
@@ -26,6 +26,18 @@
|
||||
#include <ed25519.h>
|
||||
#include <type_traits>
|
||||
|
||||
extern "C" {
|
||||
#include "api.h"
|
||||
}
|
||||
|
||||
#ifndef CRYPTO_PUBLICKEYBYTES
|
||||
#define CRYPTO_PUBLICKEYBYTES pqcrystals_dilithium2_PUBLICKEYBYTES
|
||||
#endif
|
||||
|
||||
#ifndef crypto_sign_verify
|
||||
#define crypto_sign_verify pqcrystals_dilithium2_ref_verify
|
||||
#endif
|
||||
|
||||
namespace ripple {
|
||||
|
||||
std::ostream&
|
||||
@@ -213,6 +225,10 @@ publicKeyType(Slice const& slice)
|
||||
|
||||
if (slice[0] == 0x02 || slice[0] == 0x03)
|
||||
return KeyType::secp256k1;
|
||||
}
|
||||
else if (slice.size() == CRYPTO_PUBLICKEYBYTES)
|
||||
{
|
||||
return KeyType::dilithium;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
@@ -295,6 +311,11 @@ verify(
|
||||
m.data(), m.size(), publicKey.data() + 1, sig.data()) ==
|
||||
0;
|
||||
}
|
||||
else if (*type == KeyType::dilithium)
|
||||
{
|
||||
return crypto_sign_verify(
|
||||
sig.data(), sig.size(), m.data(), m.size(), publicKey.data()) == 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -25,26 +25,89 @@
|
||||
#include <ripple/protocol/SecretKey.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
#include <ripple/protocol/impl/secp256k1.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <ed25519.h>
|
||||
|
||||
#pragma push_macro("L")
|
||||
#pragma push_macro("K")
|
||||
#pragma push_macro("N")
|
||||
#pragma push_macro("S")
|
||||
#pragma push_macro("U")
|
||||
#pragma push_macro("D")
|
||||
#undef L
|
||||
#undef K
|
||||
#undef N
|
||||
#undef S
|
||||
#undef U
|
||||
#undef D
|
||||
|
||||
extern "C" {
|
||||
#include "api.h"
|
||||
#include "fips202.h"
|
||||
#include "packing.h"
|
||||
#include "params.h"
|
||||
#include "poly.h"
|
||||
#include "polyvec.h"
|
||||
#include "sign.h"
|
||||
}
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
// Define the dilithium functions and sizes with respect to functions named here
|
||||
#ifndef CRYPTO_PUBLICKEYBYTES
|
||||
#define CRYPTO_PUBLICKEYBYTES pqcrystals_dilithium2_PUBLICKEYBYTES
|
||||
#endif
|
||||
|
||||
#ifndef CRYPTO_SECRETKEYBYTES
|
||||
#define CRYPTO_SECRETKEYBYTES pqcrystals_dilithium2_SECRETKEYBYTES
|
||||
#endif
|
||||
|
||||
#ifndef CRYPTO_BYTES
|
||||
#define CRYPTO_BYTES pqcrystals_dilithium2_BYTES
|
||||
#endif
|
||||
|
||||
#ifndef crypto_sign_keypair
|
||||
#define crypto_sign_keypair pqcrystals_dilithium2_ref_keypair
|
||||
#endif
|
||||
|
||||
#ifndef crypto_sign_signature
|
||||
#define crypto_sign_signature pqcrystals_dilithium2_ref_signature
|
||||
#endif
|
||||
|
||||
namespace ripple {
|
||||
|
||||
SecretKey::~SecretKey()
|
||||
{
|
||||
secure_erase(buf_, sizeof(buf_));
|
||||
secure_erase(buf_, size_);
|
||||
}
|
||||
|
||||
SecretKey::SecretKey(std::array<std::uint8_t, 32> const& key)
|
||||
{
|
||||
size_ = 32;
|
||||
std::memcpy(buf_, key.data(), key.size());
|
||||
}
|
||||
|
||||
SecretKey::SecretKey(std::array<std::uint8_t, 2528> const& key)
|
||||
{
|
||||
size_ = 2528;
|
||||
std::memcpy(buf_, key.data(), key.size());
|
||||
}
|
||||
|
||||
SecretKey::SecretKey(Slice const& slice)
|
||||
{
|
||||
if (slice.size() != sizeof(buf_))
|
||||
if (slice.size() != 32 && slice.size() != 2528)
|
||||
{
|
||||
LogicError("SecretKey::SecretKey: invalid size");
|
||||
std::memcpy(buf_, slice.data(), sizeof(buf_));
|
||||
}
|
||||
size_ = slice.size();
|
||||
std::memcpy(buf_, slice.data(), size_);
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -234,6 +297,18 @@ signDigest(PublicKey const& pk, SecretKey const& sk, uint256 const& digest)
|
||||
return Buffer{sig, len};
|
||||
}
|
||||
|
||||
std::string
|
||||
toHexString(const uint8_t* data, size_t length)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
oss << std::uppercase << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< static_cast<int>(data[i]);
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
Buffer
|
||||
sign(PublicKey const& pk, SecretKey const& sk, Slice const& m)
|
||||
{
|
||||
@@ -269,7 +344,13 @@ sign(PublicKey const& pk, SecretKey const& sk, Slice const& m)
|
||||
secp256k1Context(), sig, &len, &sig_imp) != 1)
|
||||
LogicError(
|
||||
"sign: secp256k1_ecdsa_signature_serialize_der failed");
|
||||
|
||||
|
||||
return Buffer{sig, len};
|
||||
}
|
||||
case KeyType::dilithium: {
|
||||
uint8_t sig[CRYPTO_BYTES];
|
||||
size_t len;
|
||||
crypto_sign_signature(sig, &len, m.data(), m.size(), sk.data());
|
||||
return Buffer{sig, len};
|
||||
}
|
||||
default:
|
||||
@@ -280,11 +361,143 @@ sign(PublicKey const& pk, SecretKey const& sk, Slice const& m)
|
||||
SecretKey
|
||||
randomSecretKey()
|
||||
{
|
||||
std::uint8_t buf[32];
|
||||
beast::rngfill(buf, sizeof(buf), crypto_prng());
|
||||
SecretKey sk(Slice{buf, sizeof(buf)});
|
||||
secure_erase(buf, sizeof(buf));
|
||||
return sk;
|
||||
return randomSecretKey(KeyType::secp256k1);
|
||||
}
|
||||
|
||||
SecretKey
|
||||
randomSecretKey(KeyType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case KeyType::ed25519:
|
||||
case KeyType::secp256k1: {
|
||||
std::uint8_t buf[32];
|
||||
beast::rngfill(buf, sizeof(buf), crypto_prng());
|
||||
SecretKey sk(Slice{buf, sizeof(buf)});
|
||||
secure_erase(buf, sizeof(buf));
|
||||
return sk;
|
||||
}
|
||||
case KeyType::dilithium: {
|
||||
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
|
||||
uint8_t buf[CRYPTO_SECRETKEYBYTES];
|
||||
crypto_sign_keypair(pk, buf);
|
||||
SecretKey sk(Slice{buf, CRYPTO_SECRETKEYBYTES});
|
||||
secure_erase(buf, sizeof(buf));
|
||||
return sk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
expand_mat(polyvecl mat[K], const uint8_t rho[SEEDBYTES])
|
||||
{
|
||||
unsigned int i, j;
|
||||
uint16_t nonce;
|
||||
|
||||
for (i = 0; i < K; ++i)
|
||||
{
|
||||
for (j = 0; j < L; ++j)
|
||||
{
|
||||
nonce = (i << 8) + j; // Combine indices i and j into a nonce
|
||||
poly_uniform(&mat[i].vec[j], rho, nonce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pqcrystals_dilithium2_ref_keypair_seed(
|
||||
uint8_t* pk,
|
||||
uint8_t* sk,
|
||||
const uint8_t* seed)
|
||||
{
|
||||
uint8_t seedbuf[3 * SEEDBYTES];
|
||||
uint8_t tr[CRHBYTES];
|
||||
const uint8_t* rho;
|
||||
const uint8_t* rhoprime;
|
||||
const uint8_t* key;
|
||||
polyvecl mat[K], s1, s1hat;
|
||||
polyveck t1, t0, s2;
|
||||
unsigned int i;
|
||||
|
||||
/* Use the provided seed to generate rho, rhoprime, and key */
|
||||
shake256(seedbuf, 3 * SEEDBYTES, seed, SEEDBYTES);
|
||||
rho = seedbuf;
|
||||
rhoprime = rho + SEEDBYTES;
|
||||
key = rhoprime + SEEDBYTES;
|
||||
|
||||
/* Expand matrix */
|
||||
expand_mat(mat, rho);
|
||||
|
||||
/* Sample short vectors s1 and s2 using rhoprime */
|
||||
polyvecl_uniform_eta(&s1, rhoprime, 0);
|
||||
polyveck_uniform_eta(&s2, rhoprime, L);
|
||||
|
||||
/* Compute t = As1 + s2 */
|
||||
s1hat = s1;
|
||||
polyvecl_ntt(&s1hat);
|
||||
for (i = 0; i < K; ++i)
|
||||
{
|
||||
polyvecl_pointwise_acc_montgomery(&t1.vec[i], &mat[i], &s1hat);
|
||||
poly_invntt_tomont(&t1.vec[i]);
|
||||
}
|
||||
polyveck_add(&t1, &t1, &s2);
|
||||
|
||||
/* Extract t1 and write public key */
|
||||
polyveck_caddq(&t1);
|
||||
polyveck_power2round(&t1, &t0, &t1);
|
||||
pack_pk(pk, rho, &t1);
|
||||
|
||||
/* Hash rho and t1 to obtain tr */
|
||||
uint8_t buf[CRYPTO_PUBLICKEYBYTES];
|
||||
memcpy(buf, pk, CRYPTO_PUBLICKEYBYTES);
|
||||
shake256(tr, CRHBYTES, buf, CRYPTO_PUBLICKEYBYTES);
|
||||
|
||||
/* Pack secret key */
|
||||
pack_sk(sk, rho, tr, key, &t0, &s1, &s2);
|
||||
|
||||
/* Clean sensitive data */
|
||||
secure_erase(seedbuf, sizeof(seedbuf));
|
||||
secure_erase((void*)&s1, sizeof(s1));
|
||||
secure_erase((void*)&s1hat, sizeof(s1hat));
|
||||
secure_erase((void*)&s2, sizeof(s2));
|
||||
secure_erase((void*)&t0, sizeof(t0));
|
||||
secure_erase((void*)&t1, sizeof(t1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pqcrystals_dilithium2_ref_publickey(uint8_t* pk, const uint8_t* sk)
|
||||
{
|
||||
uint8_t seedbuf[3 * SEEDBYTES + 2 * CRHBYTES];
|
||||
uint8_t *rho, *tr, *key;
|
||||
polyvecl mat[K], s1, s1hat;
|
||||
polyveck t0, t1, s2;
|
||||
|
||||
rho = seedbuf;
|
||||
tr = rho + SEEDBYTES;
|
||||
key = tr + SEEDBYTES;
|
||||
unpack_sk(rho, tr, key, &t0, &s1, &s2, sk);
|
||||
|
||||
/* Expand matrix */
|
||||
polyvec_matrix_expand(mat, rho);
|
||||
|
||||
/* Matrix-vector multiplication */
|
||||
s1hat = s1;
|
||||
polyvecl_ntt(&s1hat);
|
||||
polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat);
|
||||
polyveck_reduce(&t1);
|
||||
polyveck_invntt_tomont(&t1);
|
||||
|
||||
/* Add error vector s2 */
|
||||
polyveck_add(&t1, &t1, &s2);
|
||||
|
||||
/* Extract t1 and write public key */
|
||||
polyveck_caddq(&t1);
|
||||
polyveck_power2round(&t1, &t0, &t1);
|
||||
pack_pk(pk, rho, &t1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
SecretKey
|
||||
@@ -306,6 +519,17 @@ generateSecretKey(KeyType type, Seed const& seed)
|
||||
return sk;
|
||||
}
|
||||
|
||||
if (type == KeyType::dilithium)
|
||||
{
|
||||
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
|
||||
uint8_t buf[CRYPTO_SECRETKEYBYTES];
|
||||
auto key = sha512Half_s(Slice(seed.data(), seed.size()));
|
||||
pqcrystals_dilithium2_ref_keypair_seed(pk, buf, key.data());
|
||||
SecretKey sk{Slice{buf, CRYPTO_SECRETKEYBYTES}};
|
||||
secure_erase(buf, CRYPTO_SECRETKEYBYTES);
|
||||
return sk;
|
||||
}
|
||||
|
||||
LogicError("generateSecretKey: unknown key type");
|
||||
}
|
||||
|
||||
@@ -342,6 +566,14 @@ derivePublicKey(KeyType type, SecretKey const& sk)
|
||||
ed25519_publickey(sk.data(), &buf[1]);
|
||||
return PublicKey(Slice{buf, sizeof(buf)});
|
||||
}
|
||||
case KeyType::dilithium: {
|
||||
uint8_t pk_data[CRYPTO_PUBLICKEYBYTES];
|
||||
if (pqcrystals_dilithium2_ref_publickey(pk_data, sk.data()) != 1)
|
||||
LogicError(
|
||||
"derivePublicKey: secp256k1_ec_pubkey_serialize failed");
|
||||
|
||||
return PublicKey{Slice{pk_data, CRYPTO_PUBLICKEYBYTES}};
|
||||
}
|
||||
default:
|
||||
LogicError("derivePublicKey: bad key type");
|
||||
};
|
||||
@@ -356,18 +588,23 @@ generateKeyPair(KeyType type, Seed const& seed)
|
||||
detail::Generator g(seed);
|
||||
return g(0);
|
||||
}
|
||||
default:
|
||||
case KeyType::ed25519: {
|
||||
auto const sk = generateSecretKey(type, seed);
|
||||
return {derivePublicKey(type, sk), sk};
|
||||
}
|
||||
case KeyType::dilithium: {
|
||||
auto const sk = generateSecretKey(type, seed);
|
||||
return {derivePublicKey(type, sk), sk};
|
||||
}
|
||||
default:
|
||||
throw std::invalid_argument("Unsupported key type");
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<PublicKey, SecretKey>
|
||||
randomKeyPair(KeyType type)
|
||||
{
|
||||
auto const sk = randomSecretKey();
|
||||
auto const sk = randomSecretKey(type);
|
||||
return {derivePublicKey(type, sk), sk};
|
||||
}
|
||||
|
||||
@@ -378,9 +615,16 @@ parseBase58(TokenType type, std::string const& s)
|
||||
auto const result = decodeBase58Token(s, type);
|
||||
if (result.empty())
|
||||
return std::nullopt;
|
||||
if (result.size() != 32)
|
||||
if (result.size() != 32 && result.size() != 2528)
|
||||
return std::nullopt;
|
||||
return SecretKey(makeSlice(result));
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#pragma pop_macro("K")
|
||||
#pragma pop_macro("L")
|
||||
#pragma pop_macro("N")
|
||||
#pragma pop_macro("S")
|
||||
#pragma pop_macro("U")
|
||||
#pragma pop_macro("D")
|
||||
|
||||
@@ -100,10 +100,38 @@ class Wildcard_test : public beast::unit_test::suite
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testSimplePayment(FeatureBitset features)
|
||||
{
|
||||
using namespace test::jtx;
|
||||
|
||||
testcase("simple payment");
|
||||
|
||||
Env env{*this, envconfig(), features};
|
||||
Account const alice{"alice"};
|
||||
Account const bob{"bob"};
|
||||
Account const carol{"carol"};
|
||||
Account const dave{"dave", KeyType::dilithium};
|
||||
env.fund(XRP(1000), alice, bob, carol, dave);
|
||||
env.close();
|
||||
|
||||
env(fset(dave, asfForceQuantum));
|
||||
env(pay(dave, bob, XRP(100)));
|
||||
env.close();
|
||||
|
||||
Json::Value params;
|
||||
params[jss::ledger_index] = env.current()->seq() - 1;
|
||||
params[jss::transactions] = true;
|
||||
params[jss::expand] = true;
|
||||
auto const jrr = env.rpc("json", "ledger", to_string(params));
|
||||
std::cout << jrr << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
testWithFeats(FeatureBitset features)
|
||||
{
|
||||
testWildcardSign(features);
|
||||
// testWildcardSign(features);
|
||||
testSimplePayment(features);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -366,7 +366,7 @@ public:
|
||||
std::array<PublicKey, 32> keys;
|
||||
|
||||
for (std::size_t i = 0; i != keys.size(); ++i)
|
||||
keys[i] = derivePublicKey(keyType, randomSecretKey());
|
||||
keys[i] = derivePublicKey(keyType, randomSecretKey(keyType));
|
||||
|
||||
for (std::size_t i = 0; i != keys.size(); ++i)
|
||||
{
|
||||
@@ -431,6 +431,54 @@ public:
|
||||
}
|
||||
|
||||
testBase58(KeyType::ed25519);
|
||||
|
||||
// testcase("Base58: dilithium");
|
||||
|
||||
// {
|
||||
// auto const pk1 = derivePublicKey(
|
||||
// KeyType::dilithium,
|
||||
// generateSecretKey(
|
||||
// KeyType::dilithium, generateSeed("masterpassphrase")));
|
||||
|
||||
// auto const pk2 = parseBase58<PublicKey>(
|
||||
// TokenType::NodePublic,
|
||||
// "p9pow2SA5t1GpXJCZiWeWiKjZ4xav57jYgDzAhesVequQtwp2UMQ1ezUUE81t7"
|
||||
// "QY7zyvWqsRCTuxDAyZikit8Qwrr3Gcq5nNdW9DzbqjiY18Ze5ZZCdpNmkcsye6"
|
||||
// "MajNjTrjbr7VzcH2HksZnRB6gTiy8Ktm3s6jwU9wiDHo3kbZdY1UbV9MZXSweg"
|
||||
// "abP9s1oFRMSCZ3UQJAPHBVeCyd9LCp4oV3kj3TVSo7VF8D5xzgwFvtiwXxcAae"
|
||||
// "sKnG5u1NgyYPFNqXFZA48ezBjmsYTt5ZKcKcCShkKa5tN4dME4NCagDa9G8U24"
|
||||
// "8HShgFkVHCwjpRcyAEPehN9TUowySQZZFNQu8887sQ1M22BJ6rmSkfLAbV6jpm"
|
||||
// "HinSjURu67SZ1vvNm5rmEEcLvpMwHibwJQkurVD7LYXUJrL2uXUf5AiuZycJEi"
|
||||
// "1XZcd6sQaNAp64FPecRzWMnLM9eqg2nJQGt9YP7Gv6S2JV5m3AULsebDDZ1hYR"
|
||||
// "7CUNfAeo3Dj6SoatPJaqED5GfQK2Z451QHQr9FQXsLMJ9bfXhQDJJYTa3kKyo9"
|
||||
// "1wtaZataHyhDaGpJ3WwuDV1adkfgcrMLbK52mi6Qqznm22WQRxVtp2heuEees9"
|
||||
// "zGgSnfWhFSQ7QNaQStQ9jdPErqQFmscN6Evq1b283ABuJk22EKMPz1JWJmPXvy"
|
||||
// "rUKFwqf5u5AXkZVZZ8zEPmoLzsNoFVBDneAt2FbAh5n45rfUQs1BFeFEn6wcfY"
|
||||
// "mh61t4xdzcSZpcJHHZWqRXBaPFWbgHKqWmxnnwdMZik565WuPmQhD7BpcmbMsx"
|
||||
// "ffS8QEqPgwKAHNSnrGw7ZZf2nsb6C37ydmVecswmjRVosCTsBniBxLvDzzcGpa"
|
||||
// "oyyG7RD6X8bAKmSyD9VJFtwqXWj8hi9d6P729cwuthmzUhmTsYYiSCy4aoPM8o"
|
||||
// "U3pHheiydExXeifbXubwvS3LKAk48dyVCN1LhcwELn8hzUqnZ79whzFR72CPhv"
|
||||
// "DQgZU9NmG7SBZteV3P5oTEdWeqFwGf9umZQbMAGoaCfjE27zgjzd6GfFsZ6AUn"
|
||||
// "2xCrEfwoEg4uhB9PC9QsturSWWV88S1YTtR7pbEbGtEVBgTkcNMSk2XijUJBGC"
|
||||
// "r83964fMtsbuj9DyqJgQSg1za6cHfgJt9pzmVoCNBRoBLGcsWn8CZAcxUGZkhm"
|
||||
// "k2nwERPsCci56kV2UEfTKpq4PqUYWmxi2fvbvamqCWv6kQgBA3FLWXu8rXtsa9"
|
||||
// "vUx2fV1jiVogFRewsxZ3YCdmAVNmt89jb2ECQX4rdEqDXwfWJPxRUY2JD3JSZi"
|
||||
// "jWpHVqMJiHGu6KgeGvCcGmiqBvYom3D9ACQxA9QGTCdQh4AYYYjSwDabA7nB4A"
|
||||
// "EVw2v5L7Z2uz76BHXMcWCHu1B3q57kVihrNfKYGDLcscw9TebPKTimZEqV2PB3"
|
||||
// "h5YA9P9VKgnRKmkFr8qMQRrVR2ekGafMB2PVRmrMLkZkYNx9exE1mvkN7VoD4t"
|
||||
// "QyRzQNsSh3xJq6PdBYX5KTm5ouw7DVxev4PQUNiHtZVExZGfjykgzoRojvD7s7"
|
||||
// "64BpWNyyRAU4zyMT5UU1BdtBQQzdMxxZWMsH6LHkX7dahTPkGAEtQn1gPrJdLP"
|
||||
// "uPtryue9ps2wNpVWT8T1Riw5fXgZ4NHfJb5hRwX95vg1WKXYMttHMBL6Zi7QEf"
|
||||
// "9VSdrt2qTw3MTG3F4A3uxJhyapzv1XBfxdKUTRbEh3h59CTmxLZauPBKE2QW5a"
|
||||
// "jDUwoZKv9cV6isLfNe49XYSWa4ger9X3Gfga8xxPrmaxnWeST2qjfUkhuqi44F"
|
||||
// "v");
|
||||
|
||||
// BEAST_EXPECT(pk2);
|
||||
|
||||
// BEAST_EXPECT(pk1 == *pk2);
|
||||
// }
|
||||
|
||||
// testBase58(KeyType::dilithium);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -220,6 +220,135 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
testcase("Node keypair generation & signing (dilithium)");
|
||||
|
||||
auto const secretKey = generateSecretKey(
|
||||
KeyType::dilithium, generateSeed("masterpassphrase"));
|
||||
auto const publicKey =
|
||||
derivePublicKey(KeyType::dilithium, secretKey);
|
||||
|
||||
BEAST_EXPECT(
|
||||
toBase58(TokenType::NodePublic, publicKey) ==
|
||||
"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"
|
||||
"v");
|
||||
BEAST_EXPECT(
|
||||
toBase58(TokenType::NodePrivate, secretKey) ==
|
||||
"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");
|
||||
BEAST_EXPECT(
|
||||
to_string(calcNodeID(publicKey)) ==
|
||||
"8A94F2BC52E94646EC83CD988657FE37A9D5CDB5");
|
||||
|
||||
auto sig = sign(publicKey, secretKey, makeSlice(message1));
|
||||
BEAST_EXPECT(sig.size() != 0);
|
||||
BEAST_EXPECT(verify(publicKey, makeSlice(message1), sig));
|
||||
|
||||
// Correct public key but wrong message
|
||||
BEAST_EXPECT(!verify(publicKey, makeSlice(message2), sig));
|
||||
|
||||
// Verify with incorrect public key
|
||||
{
|
||||
auto const otherPublicKey = derivePublicKey(
|
||||
KeyType::ed25519,
|
||||
generateSecretKey(
|
||||
KeyType::ed25519, generateSeed("otherpassphrase")));
|
||||
|
||||
BEAST_EXPECT(!verify(otherPublicKey, makeSlice(message1), sig));
|
||||
}
|
||||
|
||||
// Correct public key but wrong signature
|
||||
{
|
||||
// Slightly change the signature:
|
||||
if (auto ptr = sig.data())
|
||||
ptr[sig.size() / 2]++;
|
||||
|
||||
BEAST_EXPECT(!verify(publicKey, makeSlice(message1), sig));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
testcase("Account keypair generation & signing (secp256k1)");
|
||||
|
||||
@@ -303,6 +432,132 @@ public:
|
||||
BEAST_EXPECT(!verify(pk, makeSlice(message1), sig));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
testcase("Account keypair generation & signing (dilithium)");
|
||||
|
||||
auto const [pk, sk] = generateKeyPair(
|
||||
KeyType::dilithium, generateSeed("masterpassphrase"));
|
||||
|
||||
BEAST_EXPECT(
|
||||
to_string(calcAccountID(pk)) ==
|
||||
"rDdkg2HADzqCh6s6CyZ53ExSQ3fRMEycuV");
|
||||
BEAST_EXPECT(
|
||||
toBase58(TokenType::AccountPublic, pk) ==
|
||||
"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"
|
||||
"C");
|
||||
BEAST_EXPECT(
|
||||
toBase58(TokenType::AccountSecret, sk) ==
|
||||
"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");
|
||||
|
||||
auto sig = sign(pk, sk, makeSlice(message1));
|
||||
BEAST_EXPECT(sig.size() != 0);
|
||||
BEAST_EXPECT(verify(pk, makeSlice(message1), sig));
|
||||
|
||||
// Correct public key but wrong message
|
||||
BEAST_EXPECT(!verify(pk, makeSlice(message2), sig));
|
||||
|
||||
// Verify with incorrect public key
|
||||
{
|
||||
auto const otherKeyPair = generateKeyPair(
|
||||
KeyType::ed25519, generateSeed("otherpassphrase"));
|
||||
|
||||
BEAST_EXPECT(
|
||||
!verify(otherKeyPair.first, makeSlice(message1), sig));
|
||||
}
|
||||
|
||||
// Correct public key but wrong signature
|
||||
{
|
||||
// Slightly change the signature:
|
||||
if (auto ptr = sig.data())
|
||||
ptr[sig.size() / 2]++;
|
||||
|
||||
BEAST_EXPECT(!verify(pk, makeSlice(message1), sig));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user