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: add from field method #87

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open

Conversation

kashbrti
Copy link
Contributor

Description

added a method to create bignums from field elements

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.

@@ -99,6 +101,15 @@ pub trait BigNumTrait {
pub fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self;
}

// impl<let N: u32, let MOD_BITS: u32, Params> std::convert::From<Field> for BigNum<N, MOD_BITS, Params>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ideally I would like to use this method, but there's an issue with a similar impl in U60Repr

) -> [Field; N] {
let result = __from_field::<N>(field);
// validate the limbs are in range and the value in total is less than 2^254
validate_in_range::<N, 254>(result);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wonder if there's a bug here. it might be that the result is 254 bits long but larger than the field modulus.
Should I create a field params and do a validate_in_field?

@@ -57,6 +58,29 @@ impl<let N: u32, let NumSegments: u32> std::convert::From<[Field; N]> for U60Rep
}
}

// impl<let N: u32, let NumSegments: u32> std::convert::From<Field> for U60Repr<N, NumSegments> {
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 would be my preferred way of doing the casting for U60Repr but the issue is as soon as I have the conversion like this, I can not use U60repr::from() anymore. because it does not know the type generic. @TomAFrench any suggestions on how to fix this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@TomAFrench, I'm just pinging you to see if you have an idea if we can fix this.

let mut result: Self = U60Repr { limbs: [0; N * NumSegments] };
let N_u60: u32 = N * NumSegments;
assert(N_u60 >= 1, "N must be at least 1");
if N_u60 == 1 {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

very ugly, very ugly. but I'm not sure if there's a workaround.

params: P<N, MOD_BITS>,
field: Field,
) -> [Field; N] {
let result = __from_field::<N>(field);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be in an unsafe block with a safety comment describing why it’s safe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, I'll add comments explaining the safety.

@@ -790,3 +790,10 @@ fn test_expressions() {
assert(wx_constrained.limbs == wx.limbs);
}

#[test]
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess missing a test case where Field is large enough so it will produce 2 limbs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added tests for 2 and 3 digits.

grumpkin_modulus[0] = 0x33e84879b9709143e1f593f0000001;
grumpkin_modulus[1] = 0x4e72e131a029b85045b68181585d28;
grumpkin_modulus[2] = 0x3064;
validate_gt::<N, 254>(grumpkin_modulus, result);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we have to check the 254-bit bignum returned by __from_field is actually a grumpkin field element.
to do this I'm using the validate_gt function and comparing the result to the grumpkin_modulus.

At first, I wanted to use the validate_in_field function, but the issue is, it only works when the generics match the generics used to create the field (in this case grumpkin_Fq which will have 3 limbs. So instead I just did the validate_gt check.

@kashbrti kashbrti marked this pull request as ready for review January 6, 2025 15:45
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.

2 participants