> For the complete documentation index, see [llms.txt](https://docs.xrpl-commons.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xrpl-commons.org/core-dev-bootcamp/module05/homeworks/homework1.md).

# Homework 1: Building Quantum-Resistant Signatures for XRPL

[← Back to Protocol Extensions and Quantum Signatures](/core-dev-bootcamp/module05.md)

***

### 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](https://github.com/Transia-RnD/rippled/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.cmake` to fetch/build Dilithium-2 (randomized signing + AES support).
* Provide imported targets: `NIH::dilithium2_ref`, `NIH::dilithium2aes_ref`, `NIH::fips202_ref`.
* Add `include(deps/dilithium)` to `CMakeLists.txt`.
* Link `NIH::dilithium2_ref` in `cmake/RippledCore.cmake`.
* Clean and rebuild:

```bash
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 10
```

#### 2. Amendment Feature

* Add to `features.macro`:

```cpp
XRPL_FEATURE(Quantum, Supported::yes, VoteBehavior::DefaultNo)
```

#### 3. Key Type & Cryptographic Classes

* Add `dilithium = 2` to `KeyType.h`; update `keyTypeFromString()` and `to_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 = 0x02000000` to `LedgerFormats.h`.
* Add `asfForceQuantum = 11` to `TxFlags.h`.
* Update `SetAccount.cpp` for setting/clearing the flag.
* In `Transactor.cpp::checkSign()`:
  * If `lsfForceQuantum` set, reject non-Dilithium signatures.

#### 5. Initial Tests

* Create `src/test/app/MyTests_test.cpp` covering:
  * Key generation
  * Dilithium signature verification
  * Payment signed with Dilithium
  * ForceQuantum flag behavior

#### 6. Test Execution

```bash
cmake --build . --target rippled --parallel 10 && ./rippled -u ripple.app.MyTests
```

#### 7. Quantum Key Ledger Entry

* Add `QUANTUM_KEY = 'Q'` to `LedgerNameSpace`.
* In `ledger_entries.macro`:

```cpp
LEDGER_ENTRY(ltQUANTUM_KEY, 0x0071, QuantumKey, quantumKey, ({
  {sfAccount,              soeREQUIRED},
  {sfQuantumPublicKey,     soeREQUIRED},
  {sfPreviousTxnID,        soeREQUIRED},
  {sfPreviousTxnLgrSeq,    soeREQUIRED},
  {sfOwnerNode,            soeREQUIRED},
}))
```

* Add field in `sfields.macro`:

```cpp
TYPED_SFIELD(sfQuantumPublicKey, VL, 19)
```

* Keylet helper (`Indexes.cpp` + header):

```cpp
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`:

```cpp
TRANSACTION(ttSET_QUANTUM_KEY, 25, SetQuantumKey, Delegation::notDelegatable, ({
  {sfQuantumPublicKey, soeREQUIRED},
}))
```

* Implement `SetQuantumKey.h/.cpp`:

```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:

1. Build System
   * Added CMake module snippet
   * Commands used (copy/paste)
   * Screenshot of successful build linking Dilithium
2. Amendment & Protocol
   * Feature declaration
   * KeyType + class changes summary
3. Ledger & Transactions
   * Quantum key ledger entry definition
   * SetQuantumKey transaction workflow
4. Code Snippets
   * PublicKey/SecretKey modifications
   * checkSign() Dilithium branch
5. Tests
   * Test file paths
   * Output from `./rippled -u ripple.app.MyTests`
6. Validation
   * Sample Dilithium key pair sizes
   * Example SetQuantumKey transaction JSON
   * Example Payment signed with Dilithium
7. 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](https://github.com/Transia-RnD/rippled/commit/bc8f0c2e13002887d57e69e27eafd0f11260bac2)
