Skip to content

feat(ring): introduce RingElement API and bump version to 1.4.0 - #53

Merged
Tranduy1dol merged 2 commits into
mainfrom
feat/ring-element
Jan 7, 2026
Merged

feat(ring): introduce RingElement API and bump version to 1.4.0#53
Tranduy1dol merged 2 commits into
mainfrom
feat/ring-element

Conversation

@Tranduy1dol

@Tranduy1dol Tranduy1dol commented Jan 6, 2026

Copy link
Copy Markdown
Owner
  • Add RingElement<C> for polynomial arithmetic in $R_q = \mathbb{Z}_q[X]/(X^N + 1)$ with dual-state (coefficient/NTT) representation and lazy conversion.
  • Make lumen_math::ring module public for direct access.
  • Update CHANGELOG, README, and tests to document and validate the new API.
  • Bump crate version to 1.4.0.

Summary by CodeRabbit

  • New Features

    • Added RingElement type for lattice-based polynomial math with dual representations (coefficient ↔ NTT) and automatic/lazy conversion.
    • Arithmetic support: addition, subtraction, multiplication, negation, scaling, and equality across representations.
  • Documentation

    • New Ring Elements docs and examples, plus architecture/theory notes showing usage and performance guidance.
  • Tests

    • Comprehensive tests covering construction, conversions, arithmetic, edge cases, and formatting.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add `RingElement<C>` for polynomial arithmetic in $R_q = \mathbb{Z}_q[X]/(X^N + 1)$ with dual-state (coefficient/NTT) representation and lazy conversion.
- Make `lumen_math::ring` module public for direct access.
- Update CHANGELOG, README, and tests to document and validate the new API.
- Bump crate version to `1.4.0`.
@coderabbitai

coderabbitai Bot commented Jan 6, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR adds a new public RingElement<C> type with dual-state (coefficient ↔ NTT) lazy conversions, arithmetic (Add, Sub, Mul, Neg) for owned and borrowed values, state management and accessors, shared Arc<NttContext<C>> usage, public ring module exports, documentation, and integration tests.

Changes

Cohort / File(s) Summary
Changelog & docs
CHANGELOG.md, README.md, THEORY.md
Added 1.4.0 entry and documentation describing the RingElement API, examples, and a Ring Elements subsection in THEORY.md (appears duplicated in diff).
Package & crate wiring
Cargo.toml, src/lib.rs, src/ring/mod.rs
Bumped version to 1.4.0; added pub mod ring; and re-exported RingElement and RingElementState.
Core implementation
src/ring/element.rs
New RingElement<C: FieldConfig> with RingElementState enum, private data storage, Arc<NttContext<C>> context, constructors (new, from_ntt, zero, one), state conversion methods (to_ntt, to_coefficient, into_*, clone_to_*), accessors, is_zero, scale, trait impls for Add, Sub, Mul, Neg (owned & ref), PartialEq/Eq, and Debug/Display. Enforces context consistency and performs lazy conversions.
Tests
tests/ring_element_test.rs
New integration tests exercising construction, conversions, arithmetic across states, scaling, equality across states, mixed-state operations, and expected panic cases (dimension/context mismatches).

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Caller
participant A as RingElement A
participant B as RingElement B
participant Ctx as NttContext (Arc)
Note right of A: possible states\n(Coef or NTT)
Note right of B: possible states\n(Coef or NTT)
Caller->>A: request Mul(B)
alt Either operand in Coefficient state
A->>Ctx: to_ntt(A.data)
Ctx-->>A: NTT(A)
B->>Ctx: to_ntt(B.data)
Ctx-->>B: NTT(B)
end
A->>B: pointwise multiply (NTT values)
B-->>Caller: result RingElement (NTT state, shared Ctx)
Note over Ctx,A,B: NTT context shared via Arc<NttContext>

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat: negacyclic ntt #28 — Provides the negacyclic NTT (NttContext) and operations that RingElement relies on for state conversions and pointwise multiplication.

Poem

🐰 I hop on rings of coeffs and NTT,
Lazy flips save cycles, fancy and free,
Arithmetickity blooms with shared context cheer,
Tests all green — the lattice draws near,
A happy rabbit nods: new elements are here! 🎀

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: introducing the RingElement API and bumping to version 1.4.0, both of which are central to the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI Agents
In @Cargo.toml:
- Line 4: The Cargo.toml edition value is invalid ("2024"); update the edition
entry in Cargo.toml (the line setting edition = "...") to a supported Rust
edition such as "2021" (or "2018") so Cargo can build; modify the edition value
accordingly and save the file.
🧹 Nitpick comments (2)
src/ring/element.rs (2)

227-234: Consider restricting data_mut visibility or adding safeguards.

Exposing mutable access to raw data while maintaining internal state tracking is risky. A user could modify the data in ways that invalidate the state field (e.g., manually apply partial NTT, leaving data in an inconsistent state).

Consider:

  1. Making this pub(crate) if only needed internally
  2. Adding a method that takes a closure and resets state to a known value after mutation
  3. Documenting specific safe usage patterns

272-286: Consider preserving NTT state in mixed-state addition.

When adding NTT + Coefficient, the current implementation converts both to Coefficient form (lines 282-285). However, for consistency and potential performance benefits, you might consider always converting to NTT form instead, or at least documenting this choice.

Current behavior:

  • Coefficient + Coefficient → Coefficient ✓
  • NTT + NTT → NTT ✓
  • Coefficient + NTT → Coefficient (converts RHS)
  • NTT + Coefficient → Coefficient (converts LHS)

This asymmetry means the result state depends on operand order, which could be surprising.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3734f43 and 6f02867.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • CHANGELOG.md
  • Cargo.toml
  • README.md
  • THEORY.md
  • src/lib.rs
  • src/ring/element.rs
  • src/ring/mod.rs
  • tests/ring_element_test.rs
🧰 Additional context used
🧬 Code graph analysis (2)
tests/ring_element_test.rs (1)
src/ring/element.rs (9)
  • make_ctx (491-493)
  • new (76-87)
  • zero (111-117)
  • is_zero (237-239)
  • state (133-135)
  • degree (139-141)
  • one (120-129)
  • coefficients (199-206)
  • from_ntt (97-108)
src/ring/element.rs (1)
tests/ring_element_test.rs (4)
  • make_ctx (9-11)
  • test_subtraction (82-94)
  • test_negation (97-105)
  • test_scale (143-155)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test and Coverage
🔇 Additional comments (17)
Cargo.toml (1)

3-3: Version bump to 1.4.0 is appropriate.

The minor version increment correctly reflects the addition of new public API (RingElement<C> and the public ring module) without breaking existing functionality.

THEORY.md (1)

252-268: Ring Elements documentation is clear and well-placed.

The new subsection appropriately documents the dual-state design, lazy conversion strategy, and efficiency optimizations via shared Arc<NttContext<C>>. Placement after the Negacyclic NTT section provides good contextual flow.

CHANGELOG.md (1)

8-22: Changelog entry is well-structured and comprehensive.

The 1.4.0 entry clearly documents the new RingElement<C> API, its dual-state representation, arithmetic operations, and efficiency optimizations. Separating the new type features from the module-visibility improvement in distinct subsections follows best practices.

README.md (1)

99-116: LGTM! Clear documentation with practical example.

The Ring Elements section provides a good introduction to the API. The example demonstrates the key concepts: shared NTT context via Arc, element construction, and automatic state conversion during arithmetic.

src/ring/element.rs (6)

50-65: Well-designed struct with appropriate ownership semantics.

The use of Arc<NttContext<C>> for shared NTT context is appropriate for the use case where multiple ring elements share the same ring parameters. The dual-state design is clean.


76-87: LGTM! Proper validation in constructors.

The assertion ensures data integrity by requiring the coefficient vector length to match the NTT context degree. This prevents silent bugs from mismatched dimensions.


149-193: Clean state conversion API with appropriate variants.

The three conversion patterns (in-place, consuming, cloning) provide flexibility for different use cases. The no-op behavior when already in the target state is efficient.


450-479: LGTM! Standard polynomial display format.

The Display implementation correctly shows polynomials in descending degree order with appropriate handling of the zero polynomial case.


485-610: Good unit test coverage.

The tests cover the essential functionality including state conversions, arithmetic operations, and cross-state equality. The NTT roundtrip test is particularly important for verifying the correctness of state transformations.


420-435: Do not simplify using lhs.data == rhs.data.

The explicit call to to_u1024() applies Montgomery reduction before comparison. Using FieldElement's PartialEq directly would compare raw values without this reduction, which could lead to incorrect equality checks if the values are stored in Montgomery form internally. The current implementation is correct and necessary.

Likely an incorrect or invalid review comment.

src/lib.rs (2)

15-15: LGTM! Clean module integration.

The new ring module follows the established pattern of public module declarations in the crate root.


49-51: LGTM! Appropriate public re-exports.

The re-exports of RingElement and RingElementState at the crate root level provide convenient access while maintaining the option to use the full path lumen_math::ring::* for more explicit imports.

src/ring/mod.rs (1)

1-8: LGTM! Clean module organization.

The module structure is well-organized with clear documentation and appropriate re-exports.

tests/ring_element_test.rs (4)

13-62: Good coverage of construction and state conversion APIs.

The tests thoroughly verify element construction, state transitions, and the important property that NTT roundtrips preserve coefficient values.


202-278: Excellent algebraic property tests.

Testing commutativity and distributivity provides strong confidence that the ring operations are mathematically correct. These properties are fundamental to ring arithmetic and catch subtle implementation bugs.


280-297: LGTM! Critical edge case validation.

These panic tests verify that the API correctly enforces invariants:

  1. Coefficient length must match context degree
  2. Operations require the same NTT context (via Arc::ptr_eq)

The expected strings match the panic messages in the implementation.


185-200: Good test for mixed-state operations.

This test verifies that adding elements in different states produces correct results, which is crucial for the lazy conversion feature.

Comment thread Cargo.toml
name = "lumen-math"
version = "1.3.0"
version = "1.4.0"
edition = "2024"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Invalid Rust edition "2024"—must be 2015, 2018, or 2021.

Rust does not have a 2024 edition. This will cause a cargo build failure. Correct this to a valid edition (typically "2021" for modern Rust).

🔎 Proposed fix
-edition = "2024"
+edition = "2021"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
edition = "2024"
edition = "2021"
🤖 Prompt for AI Agents
In @Cargo.toml at line 4, The Cargo.toml edition value is invalid ("2024");
update the edition entry in Cargo.toml (the line setting edition = "...") to a
supported Rust edition such as "2021" (or "2018") so Cargo can build; modify the
edition value accordingly and save the file.

@codecov

codecov Bot commented Jan 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.76923% with 30 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/ring/element.rs 80.76% 30 Missing ⚠️
Files with missing lines Coverage Δ
src/lib.rs 100.00% <ø> (ø)
src/ring/element.rs 80.76% <80.76%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…actor addition/subtraction logic, and expand tests

- Introduced `modify_data` method for safe mutation of polynomial coefficients, enforcing state consistency.
- Refactored addition and subtraction methods to simplify RHS state conversion logic.
- Expanded test coverage to validate edge cases, state transitions, format implementations, and API behavior.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/ring/element.rs (1)

237-256: Safe mutation design with minor doc clarification needed.

The modify_data method correctly ensures coefficient form before and after mutation, providing a safe API. However, the doc comment "resetting state afterward" (line 238) is slightly ambiguous—it might be clearer to say "ensuring coefficient form" since the state remains Coefficient rather than being "reset" to some default.

Optional: Clarify doc comment
-    /// Safely modifies the data using a closure, resetting state afterward.
+    /// Safely modifies the data using a closure, ensuring coefficient form.
     ///
-    /// After the mutation, the element is marked as being in coefficient form.
+    /// The element is converted to coefficient form before mutation and remains
+    /// in coefficient form afterward.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f02867 and 4b14e07.

📒 Files selected for processing (1)
  • src/ring/element.rs
🧰 Additional context used
🧬 Code graph analysis (1)
src/ring/element.rs (1)
tests/ring_element_test.rs (4)
  • make_ctx (9-11)
  • test_subtraction (82-94)
  • test_negation (97-105)
  • test_scale (143-155)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test and Coverage
🔇 Additional comments (8)
src/ring/element.rs (8)

1-65: Excellent module documentation and type design.

The dual-state representation with lazy conversion is well-explained, and the use of Arc<NttContext<C>> for shared context is an efficient design choice for lattice-based cryptography. The documentation clearly explains the purpose and usage patterns.


67-147: Well-designed constructors and accessors.

Input validation with clear panic messages, appropriate use of #[inline] for simple accessors, and correct initialization of special values (zero and one).


149-193: Efficient lazy state conversion implementation.

The no-op checks (lines 153, 163) prevent unnecessary transformations, and providing multiple conversion strategies (in-place, consuming, and cloning) gives users flexibility based on their ownership needs.


258-271: Correct utility implementations.

The is_zero method works correctly in both states (since NTT is linear), and scale appropriately preserves the current state as scalar multiplication is valid in both coefficient and NTT domains.


277-359: Correct cross-state arithmetic implementation.

Addition and subtraction properly handle operands in different states by converting RHS to match LHS, preserving the LHS state in the result. The Arc::ptr_eq check ensures context consistency, and the owned trait implementations appropriately delegate to the reference implementations.


361-424: Efficient multiplication using NTT.

The multiplication implementation correctly leverages NTT for O(n log n) polynomial multiplication instead of O(n²), and returns the result in NTT form to avoid unnecessary inverse transforms. Negation correctly preserves state since NTT is a linear transformation.


430-489: Well-implemented comparison and formatting.

Equality comparison correctly normalizes both operands to coefficient form for comparison, and the Display implementation produces readable polynomial notation (highest degree first, with special handling for the zero polynomial).


495-952: Exemplary test coverage.

The test suite is comprehensive and well-structured, covering constructors, state transitions, arithmetic operations (including cross-state scenarios), edge cases, panic conditions, accessors, formatting, and no-op optimizations. This thorough testing validates both the correctness and API usability of the implementation.

@Tranduy1dol
Tranduy1dol merged commit e385879 into main Jan 7, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant