Skip to content

Conversation

@hanno-becker
Copy link
Contributor

@hanno-becker hanno-becker commented Nov 11, 2025

Context:

We previously had two specifications for mld_montgomery_reduce:

  • A 'weak' one where the output upper bound matches the input upper bound of mld_reduce32().
  • A 'strong' one where the output interval is (-Q,Q), exclusively.

Both contracts were combined into one in a somewhat ad-hoc way (the 'weak' version being encoded as pre- and post-conditions as usual, the 'strong' version being stated as an implication in the post-condition).

The combined contract was used in the CBMC proofs of

  • mld_poly_pointwise_montgomery
  • mld_polyvecl_pointwise_acc_montgomery

There are two more functions which rely on mld_montgomery_reduce, namely

  • mld_fqmul
  • mld_fqscale

Observations:

  • The 'weak' contract of mld_montgomery_reduce is not needed: In the context of mld_poly_pointwise_montgomery and mld_polyvecl_pointwise_acc_montgomery, the strong version applies.
  • The 'strong' version also applies in the context of mld_fqmul and mld_fqscale.

Accordingly, this commit removes the 'weak' version and re-formulates the 'strong' version in traditional pre/post condition form.

The commit also removes the macro wrapper around the input bound, which I find difficult to read. It's easier to understand if the bound is explicit.

The 'strong' version only applies to mld_fqscale because of the recent modification of the iNTT output bound from 3/4*Q to Q. Otherwise, an even stronger spec would have been needed. At present, one can even remove mld_fqscale and just call mld_fqmul directly, but this commit does not do this.

The commit also takes the opportunity to add some pen-and-paper bounds reasoning for mld_montgomery_reduce.

Copy link
Contributor

@mkannwischer mkannwischer left a comment

Choose a reason for hiding this comment

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

Thanks @hanno-becker - very welcome simplification. How about we eliminate the larger bound from the documentation altogether?

@hanno-becker hanno-becker force-pushed the mld_montgomery_reduce branch 2 times, most recently from 1ced8b1 to ba6e679 Compare November 11, 2025 13:12
@hanno-becker hanno-becker force-pushed the mld_montgomery_reduce branch 2 times, most recently from 0683b6e to 608ae8f Compare November 11, 2025 15:11
Copy link
Contributor

@jammychiou1 jammychiou1 left a comment

Choose a reason for hiding this comment

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

Thank you @hanno-becker for your work! Very useful result for me to reference from the asm bound comments :D

Only two nits remaining now. Please see the comments.

@hanno-becker hanno-becker force-pushed the mld_montgomery_reduce branch 2 times, most recently from d9a332b to 4b66648 Compare November 11, 2025 15:37
Context:

We previously had two specifications for mld_montgomery_reduce:

- A 'weak' one where the output upper bound matches the input upper
  bound of mld_reduce32().
- A 'strong' one where the output interval is (-Q,Q), exclusively.

Both contracts were combined into one in a somewhat ad-hoc way
(the 'weak' version being encoded as pre- and post-conditions as
usual, the 'strong' version being stated as an implication in the
post-condition).

The combined contract was used in the CBMC proofs of
- mld_poly_pointwise_montgomery
- mld_polyvecl_pointwise_acc_montgomery

There are two more functions which rely on mld_montgomery_reduce,
namely
- mld_fqmul
- mld_fqscale

Observations:
- The 'weak' contract of mld_montgomery_reduce is not needed:
  In the context of mld_poly_pointwise_montgomery and
  mld_polyvecl_pointwise_acc_montgomery, the strong version applies.
- The 'strong' version also applies in the context of mld_fqmul
  and mld_fqscale.

Accordingly, this commit removes the 'weak' version and re-formulates
the 'strong' version in traditional pre/post condition form.

The commit also removes the macro wrapper around the input bound,
which I find difficult to read. It's easier to understand if the
bound is explicit.

The 'strong' version only applies to `mld_fqscale` because of the
recent modification of the iNTT output bound from 3/4*Q to Q. Otherwise,
an even stronger spec would have been needed. At present, one can
even remove mld_fqscale and just call mld_fqmul directly, but this
commit does not do this.

The commit also takes the opportunity to add some pen-and-paper
bounds reasoning for mld_montgomery_reduce.

Fixes #602

Signed-off-by: Hanno Becker <beckphan@amazon.co.uk>
Copy link
Contributor

@jammychiou1 jammychiou1 left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you for your hard work Hanno!

@hanno-becker hanno-becker merged commit 288bfa8 into main Nov 11, 2025
259 checks passed
@hanno-becker hanno-becker deleted the mld_montgomery_reduce branch November 11, 2025 18:33
@jakemas
Copy link
Contributor

jakemas commented Nov 11, 2025

Thanks Hanno!

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.

Reason about bounds of mld_fqmul and mld_fqscale

5 participants