# 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xrpl-commons.org/core-dev-bootcamp/module05/homeworks/homework1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
