-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Ensure that the result for PowMod is fully initialized #74585
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
Conversation
CC. @dakersnar, @sakno |
Tagging subscribers to this area: @dotnet/area-system-numerics Issue DetailsThis resolves dotnet/performance#2575 The fix provided by #74112 was not quite correct. It attempted to resolve the issue by no longer slicing the intermediate While this did fix the immediate issue, it exposed a new issue where the intermediate The root issue for #74112 was that while There are multiple ways this could be fixed, but I believe the least risky is to continue slicing Alternatively we could continue not slicing Span<uint> result = PowCore(valueCopy, value.Length, temp, power, bits);
int resultLength = Math.Min(result.Length, bits.Length);
result.CopyTo(bits); -or- We could add an additional allocation for the temporary data rather than using
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thanks for the fix. Glad we caught this.
src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.PowMod.cs
Show resolved
Hide resolved
src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.PowMod.cs
Show resolved
Hide resolved
/backport to release/7.0 |
Started backporting to release/7.0: https://github.com/dotnet/runtime/actions/runs/2935878948 |
This resolves dotnet/performance#2575
The fix provided by #74112 was not quite correct. It attempted to resolve the issue by no longer slicing the intermediate
result
to the computedresultLength
.While this did fix the immediate issue, it exposed a new issue where the intermediate
result
buffer could then be larger than the destinationbits
(the final result) buffer.The root issue for #74112 was that while
bits
is the final result buffer, it was also being used as a temporary storage location and thus could have values at indices greater thanresultLength
which were non-zero.There are multiple ways this could be fixed, but I believe the least risky is to continue slicing
result
down toresultLength
(effectively reverting the fix from #74112) and to instead explicitly clear any indices frombits
that are greater thanresult.Length
.Assuming that the computed
resultLength
is correct (and it should be or we have more serious issues), then this ensures thatbits
is exactlyresult
and all remaining indices are zero, which should ensure a correct result.Alternatively we could continue not slicing
result
whereresultLength
was being computed and instead do something like:However, this might imply that the computed
resultLength
can't be relied upon and could mask an issue in some future refactoring.-or-
We could add an additional allocation for the temporary data rather than using
bits
, which is an overall "better" change (less error prone and safer; but also more "expensive"). However, this would also be more involved and therefore riskier to take into RC2.