Homework 1: Building Quantum-Resistant Signatures for XRPL
← Back to Protocol Extensions and Quantum Signatures
Objective
Implement post-quantum (Dilithium-2) signature support in Rippled as an amendment and extend the protocol to allow accounts to opt into quantum-resistant signing and register quantum keys.
Format: Repository + written report (PDF or Markdown) with commands, screenshots, code snippets.
Reference Commit: bc8f0c2e13002887d57e69e27eafd0f11260bac2
Task
Complete all implementation steps (build integration, amendment creation, key type extension, account flag, ledger entry, new transaction type, tests) and document the process.
Requirements
1. Build System Integration (Dilithium Library)
Create
cmake/deps/dilithium.cmaketo fetch/build Dilithium-2 (randomized signing + AES support).Provide imported targets:
NIH::dilithium2_ref,NIH::dilithium2aes_ref,NIH::fips202_ref.Add
include(deps/dilithium)toCMakeLists.txt.Link
NIH::dilithium2_refincmake/RippledCore.cmake.Clean and rebuild:
cd .. && rm -r build
eval "$(pyenv init -)" && \
mkdir -p build && cd build && \
conan install .. --output-folder . --build --settings build_type=Debug && \
cmake -G Ninja \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_CXX_FLAGS=-DBOOST_ASIO_HAS_STD_INVOKE_RESULT \
-DCMAKE_BUILD_TYPE=Debug \
-DUNIT_TEST_REFERENCE_FEE=200 \
-Dtests=TRUE \
-Dxrpld=TRUE \
-Dstatic=OFF \
-Dassert=TRUE \
-Dwerr=TRUE ..
cmake --build . --target rippled --parallel 102. Amendment Feature
Add to
features.macro:
XRPL_FEATURE(Quantum, Supported::yes, VoteBehavior::DefaultNo)3. Key Type & Cryptographic Classes
Add
dilithium = 2toKeyType.h; updatekeyTypeFromString()andto_string().PublicKey:
Expand buffer to 1312 bytes (Dilithium public key size).
Implement size tracking and detection in
publicKeyType().Add Dilithium verify logic in
PublicKey.cpp.
SecretKey:
Expand to 2528 bytes (Dilithium secret key size).
Implement generator, signing support.
Implement Dilithium generation in
randomSecretKey(KeyType type).Update Base58 handling in
tokens.cpp(remove size limits blocking large keys).
4. Force Quantum Account Flag
Add
lsfForceQuantum = 0x02000000toLedgerFormats.h.Add
asfForceQuantum = 11toTxFlags.h.Update
SetAccount.cppfor setting/clearing the flag.In
Transactor.cpp::checkSign():If
lsfForceQuantumset, reject non-Dilithium signatures.
5. Initial Tests
Create
src/test/app/MyTests_test.cppcovering:Key generation
Dilithium signature verification
Payment signed with Dilithium
ForceQuantum flag behavior
6. Test Execution
cmake --build . --target rippled --parallel 10 && ./rippled -u ripple.app.MyTests7. Quantum Key Ledger Entry
Add
QUANTUM_KEY = 'Q'toLedgerNameSpace.In
ledger_entries.macro:
LEDGER_ENTRY(ltQUANTUM_KEY, 0x0071, QuantumKey, quantumKey, ({
{sfAccount, soeREQUIRED},
{sfQuantumPublicKey, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
}))Add field in
sfields.macro:
TYPED_SFIELD(sfQuantumPublicKey, VL, 19)Keylet helper (
Indexes.cpp+ header):
Keylet
quantum(AccountID const& account, Slice const& quantumPublicKey) noexcept
{
return {
ltQUANTUM_KEY,
indexHash(
LedgerNameSpace::QUANTUM_KEY,
account,
quantumPublicKey)
};
}8. SetQuantumKey Transaction
Add to
transactions.macro:
TRANSACTION(ttSET_QUANTUM_KEY, 25, SetQuantumKey, Delegation::notDelegatable, ({
{sfQuantumPublicKey, soeREQUIRED},
}))Implement
SetQuantumKey.h/.cpp:
// SetQuantumKey.cpp (skeleton)
NotTEC
SetQuantumKey::preflight(PreflightContext const& ctx)
{
if (!ctx.rules.enabled(featureQuantum))
return temDISABLED;
if (auto ret = preflight1(ctx); !isTesSuccess(ret))
return ret;
// Validate Dilithium public key format/size
return preflight2(ctx);
}
TER
SetQuantumKey::preclaim(PreclaimContext const& ctx)
{
// Check existence (keylet::quantum)
return tesSUCCESS;
}
TER
SetQuantumKey::doApply()
{
// Create ledger entry (ltQUANTUM_KEY) with sfQuantumPublicKey
return tesSUCCESS;
}9. Signature Path Validation
In
Transactor.cpp::checkSign():If Dilithium signature present:
Lookup quantum key ledger entry via
keylet::quantum.Ensure stored key matches signing key.
10. Extended Testing
Unit tests:
Quantum key index generation
Keylet lookup
Error cases (duplicate registration, invalid size)
Integration tests:
Register quantum key (SetQuantumKey)
Set ForceQuantum and submit non-Dilithium (expect failure)
Submit Dilithium-signed Payment (expect success)
Rotate quantum key (optional)
Disable amendment (temDISABLED behavior)
Deliverables
Include in the report:
Build System
Added CMake module snippet
Commands used (copy/paste)
Screenshot of successful build linking Dilithium
Amendment & Protocol
Feature declaration
KeyType + class changes summary
Ledger & Transactions
Quantum key ledger entry definition
SetQuantumKey transaction workflow
Code Snippets
PublicKey/SecretKey modifications
checkSign() Dilithium branch
Tests
Test file paths
Output from
./rippled -u ripple.app.MyTests
Validation
Sample Dilithium key pair sizes
Example SetQuantumKey transaction JSON
Example Payment signed with Dilithium
Issues & Resolutions
Any build or runtime errors and fixes
Helpful Checks
Public key size: 1312 bytes (Dilithium-2)
Secret key size: 2528 bytes
Signature size (verify expected range for Dilithium-2)
Amendment must be enabled (featureQuantum) for SetQuantumKey to succeed.
Resources
Dilithium: https://pq-crystals.org/dilithium/
Amendments: https://xrpl.org/amendments.html
Reference Commit: bc8f0c2e13002887d57e69e27eafd0f11260bac2
Last updated

