Skip to content

fix mod for mixes of Signed and Unsigned #57853

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

Merged
merged 4 commits into from
Mar 23, 2025

Conversation

oscardssmith
Copy link
Member

Previously this was just overfowing producing wrong answers (both for the sign convention and just the wrong modulo class)
fixes #57851

Previously this was just overfowing producing wrong answers (both for the sign convention and just the wrong modulo class)
fixes #57851
@oscardssmith oscardssmith added bugfix This change fixes an existing bug backport 1.10 Change should be backported to the 1.10 release backport 1.11 Change should be backported to release-1.11 backport 1.12 Change should be backported to release-1.12 maths Mathematical functions correctness bug ⚠ Bugs that are likely to lead to incorrect results in user code without throwing labels Mar 21, 2025
@StefanKarpinski
Copy link
Member

StefanKarpinski commented Mar 21, 2025

It should be noted that this changes the return type in these mixed cases, but that does seem like a bug fix. Given that the sign of the result comes from the second argument, it only seems sensible that the signedness also comes from the second argument. In fact, it would be find if the result type was simply the type of the second argument.

@oscardssmith
Copy link
Member Author

This doesn't change the result type.

@StefanKarpinski
Copy link
Member

Oh, nvm then.

@oscardssmith
Copy link
Member Author

(it actually did change the result type, but that was a bug)

@oscardssmith oscardssmith merged commit 0568917 into master Mar 23, 2025
7 checks passed
@oscardssmith oscardssmith deleted the os/fix-signed-unsigned-mod branch March 23, 2025 01:55
KristofferC pushed a commit that referenced this pull request Mar 24, 2025
Previously this was just overfowing producing wrong answers (both for
the sign convention and just the wrong modulo class)
fixes #57851

(cherry picked from commit 0568917)
@KristofferC KristofferC mentioned this pull request Mar 24, 2025
27 tasks
@KristofferC KristofferC removed the backport 1.12 Change should be backported to release-1.12 label Mar 31, 2025
KristofferC pushed a commit that referenced this pull request Mar 31, 2025
Previously this was just overfowing producing wrong answers (both for
the sign convention and just the wrong modulo class)
fixes #57851

(cherry picked from commit 0568917)
@KristofferC KristofferC mentioned this pull request Mar 31, 2025
71 tasks
KristofferC pushed a commit that referenced this pull request Mar 31, 2025
Previously this was just overfowing producing wrong answers (both for
the sign convention and just the wrong modulo class)
fixes #57851

(cherry picked from commit 0568917)
KristofferC pushed a commit that referenced this pull request Mar 31, 2025
Previously this was just overfowing producing wrong answers (both for
the sign convention and just the wrong modulo class)
fixes #57851

(cherry picked from commit 0568917)
@KristofferC
Copy link
Member

This broke DarkCurves.jl (https://s3.amazonaws.com/julialang-reports/nanosoldier/pkgeval/by_hash/4991eb8_vs_8561cc3/DarkCurves.primary.log)

Error During Test at /home/pkgeval/.julia/packages/DarkCurves/ULKGM/test/curve.test.jl:20
  Test threw exception
  Expression: double(b) == convert(ptp, double(b_ref))
  MethodError: convert(::Type{MLUInt{4, UInt64}}, ::MLInt{4, UInt64}) is ambiguous.
  
  Candidates:
    convert(::Type{MLUInt{N, T}}, x::Integer) where {N, T}
      @ DarkIntegers ~/.julia/packages/DarkIntegers/wu36S/src/multi_limb.jl:96
    convert(::Type{V}, x::MLInt{N, T}) where {V<:Unsigned, N, T}
      @ DarkIntegers ~/.julia/packages/DarkIntegers/wu36S/src/multi_limb_signed.jl:115
  
  Possible fix, define
    convert(::Type{MLUInt{N, T}}, ::MLInt{N, T}) where {T, N, N, T}
  
  Stacktrace:
    [1] rem(x::MLInt{4, UInt64}, T::Type{MLUInt{4, UInt64}})
      @ Base ./int.jl:632
    [2] +(a::MLInt{4, UInt64}, b::MLUInt{4, UInt64})
      @ Base ./int.jl:1017
    [3] mod(x::Int64, y::MLUInt{4, UInt64})
      @ Base ./int.jl:291
    [4] MgModUInt
      @ ~/.julia/packages/DarkIntegers/wu36S/src/modulo_int_montgomery.jl:42 [inlined]
    [5] convert(::Type{MgModUInt{MLUInt{4, UInt64}, {(0xfffffffefffffc2f, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff)}}}, x::Int64)
      @ Base ./number.jl:7
    [6] _promote
      @ ./promotion.jl:375 [inlined]
    [7] promote
      @ ./promotion.jl:400 [inlined]
    [8] ==(x::MgModUInt{MLUInt{4, UInt64}, {(0xfffffffefffffc2f, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff)}}, y::Int64)
      @ Base ./promotion.jl:483
    [9] +(p::DarkCurves.AffinePoint{Curve_secp256k1, MgModUInt{MLUInt{4, UInt64}, {(0xfffffffefffffc2f, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff)}}}, q::DarkCurves.AffinePoint{Curve_secp256k1, MgModUInt{MLUInt{4, UInt64}, {(0xfffffffefffffc2f, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff)}}})
      @ DarkCurves ~/.julia/packages/DarkCurves/ULKGM/src/point_affine.jl:42
   [10] double(x::DarkCurves.AffinePoint{Curve_secp256k1, MgModUInt{MLUInt{4, UInt64}, {(0xfffffffefffffc2f, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff)}}})
      @ Main ~/.julia/packages/DarkCurves/ULKGM/test/TestUtils.jl:10
   [11] macro expansion
      @ /opt/julia/share/julia/stdlib/v1.11/Test/src/Test.jl:676 [inlined]
   [12] macro expansion
      @ ~/.julia/packages/DarkCurves/ULKGM/test/curve.test.jl:20 [inlined]
   [13] (::var"#2#7")(curve_type::Type, point_type::Type)
      @ Main ~/.julia/packages/Jute/Rd9q9/src/macros.jl:112
Error During Test at /home/pkgeval/.julia/packages/DarkCurves/ULKGM/test/curve.test.jl:21

Can be reproduced with

using DarkIntegers
using DarkCurves
point_type = DarkCurves.AffinePoint
curve_type = Curve_secp256k1
stp = curve_scalar_type(curve_type)

y = stp.parameters[2]
mod(123, y)

I'll drop it from being backported.

KristofferC added a commit that referenced this pull request Apr 10, 2025
@KristofferC KristofferC removed the backport 1.11 Change should be backported to release-1.11 label Apr 10, 2025
@StefanKarpinski
Copy link
Member

StefanKarpinski commented Apr 11, 2025

@KristofferC: if it was depending on an incorrect answer, that's acceptable breakage. We are allowed to fix bugs. My understanding of this change is that it is strictly a bug fix. Or is your point just that we shouldn't include it in a patch release?

@oscardssmith
Copy link
Member Author

it's not that this was depending on an incorrect answer, it's that this is a type for which the new implementation is apparently insufficiently generic for some reason that I don't yet understand.

@KristofferC
Copy link
Member

It wasn't obvious what the lesser evil / greater good was to me, and there was some pressure to get out a 1.11 quickly, so I just went with keeping packages working. We can reconsider for next 1.11.

@KristofferC KristofferC mentioned this pull request Jun 4, 2025
75 tasks
KristofferC pushed a commit that referenced this pull request Jun 5, 2025
Previously this was just overfowing producing wrong answers (both for
the sign convention and just the wrong modulo class)
fixes #57851

(cherry picked from commit 0568917)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport 1.10 Change should be backported to the 1.10 release bugfix This change fixes an existing bug correctness bug ⚠ Bugs that are likely to lead to incorrect results in user code without throwing maths Mathematical functions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The Base functions mod(::Unsigned, ::Signed) and mod(::Signed, ::Unsigned) are broken
3 participants