Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added to_field method #99

Merged
merged 18 commits into from
Jan 27, 2025
Merged

feat: added to_field method #99

merged 18 commits into from
Jan 27, 2025

Conversation

kashbrti
Copy link
Contributor

@kashbrti kashbrti commented Jan 16, 2025

Description

added a method that allows casting bignums to Field type given the bignum is in range.
Moreover, this PR fixes issues with the range checks in the from_field method.

Problem*

Resolves

Summary*

Additional Context

PR Checklist*

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

@kashbrti kashbrti requested a review from TomAFrench January 16, 2025 14:03
@kashbrti kashbrti marked this pull request as ready for review January 17, 2025 10:31
Comment on lines 854 to 877
#[test]
fn test_to_field_three_digits() {
let field: Field = 2330301921655783950764183713945533646391233209687308929386184468126823563744;
let bn =
Fq { limbs: [0x862cf8ea69d6c70c9cc8d8871b41e0, 0xe7763528201566c2fc8d93973cf1b4, 0x526] };
let result = bn.to_field();
assert(result == field);
}

#[test(should_fail_with = "BigNum::validate_gt check fails")]
fn test_to_field_three_digits_overflow() {
let bn: Fq = BigNum {
limbs: [0x4e6405505a33bb9b9c0563df2bd59a, 0x48dbe03a9bb4865ba961e41ef9dded, 0x3a36],
};
let result = bn.to_field();
}

#[test(should_fail_with = "BigNum::validate_gt check fails")]
fn test_to_field_too_many_digits() {
let bn: BN381 = BN381 {
limbs: [0xea1742447ee9d92f9f18e1c80a481e, 0x3d89ad3d3ae85f3f482a08435c93ec, 0x1e9f, 0x1],
};
let result = bn.to_field();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

instead of failing in runtime, is it possible to implement .to_field() only for bignums that are guaranteed to be convertable to a field.

Imagine, I am writing a portal Aztec contract that computes let hash: U256 = sha256(message) and then I try to convert hash into a Field (hash.to_field()) to store it in Aztec storage. There is a high probability that hash.to_field() will fail IIRC. This will be essentially a DDOS of the portal.

I am thinking of something like:

impl<let N: u32> ToField for BigNum<N> where N: <= 254 {
  fn to_field(...) { ... }
}

Copy link
Contributor

Choose a reason for hiding this comment

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

What I mean, is that this code should not compile:

let a: U256 = BigNum::from_field(123);
a.to_field(); // compilation error

Copy link
Member

@TomAFrench TomAFrench Jan 20, 2025

Choose a reason for hiding this comment

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

You can't implement a trait conditionally based on a numeric generic value without enumerating all of them. What can be done is have a compile time check against the modulus of the field. If the field modulus won't fit into a field element then completion can be halted.

Copy link
Contributor

Choose a reason for hiding this comment

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

anything that throws a compile time error works. Better throw in compile time than DoS a portal and lock tokens forever due to a runtime throw.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm, but this would mean that we can't even have the method for U256 or even U254.

Copy link
Contributor

Choose a reason for hiding this comment

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

What about U253? Also, what about adding an additional .try_to_field that will throw if U256 is too large. Actually, it can be just U253::into and U256::try_into. Is there a TryFrom trait in Noir std?

@TomAFrench TomAFrench mentioned this pull request Jan 20, 2025
Copy link
Contributor

github-actions bot commented Jan 21, 2025

Changes to circuit sizes

Generated at commit: 6f33d75d8471c46fd933e8d3af1606a8152a78c3, compared to commit: b3000e17c4f057be85cf36e56816ea77b719e5f2

🧾 Summary (10% most significant diffs)

Program ACIR opcodes (+/-) % Circuit size (+/-) %
bench_from_field_BN256.json 0 ➖ 0.00% +6 ❌ +0.21%

Full diff report 👇
Program ACIR opcodes (+/-) % Circuit size (+/-) %
bench_from_field_BN256.json 21 (0) 0.00% 2,839 (+6) +0.21%

src/bignum.nr Outdated

// @Brief: Convert a BigNum to a Field
// we decided to not add this to the BigNumTrait as it is might lead to bad use cases of it
pub(crate) fn to_field<let N: u32, let MOD_BITS: u32, Params>(input: BigNum<N, MOD_BITS, Params>) -> Field
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is a free function now. I wonder how it would be accessed outside the lib though.

Copy link
Member

Choose a reason for hiding this comment

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

It just needs to be marked pub rather than pub(crate).

Copy link
Contributor

Choose a reason for hiding this comment

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

if it's not going to check modulus of the field at compile time, I would recommend renaming it to try_to_field to signal to the users that this function can fail in runtime

src/bignum.nr Outdated Show resolved Hide resolved
src/bignum.nr Outdated Show resolved Hide resolved
@TomAFrench TomAFrench merged commit 7c92c22 into main Jan 27, 2025
8 checks passed
@github-actions github-actions bot mentioned this pull request Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants