Skip to content

Commit

Permalink
Add sqrt, issquare, issquare_with_sqrt for gfp_fmpz_elem.
Browse files Browse the repository at this point in the history
  • Loading branch information
wbhart authored and thofma committed Dec 17, 2021
1 parent d60a400 commit 011caf2
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/flint/gfp_fmpz_elem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,50 @@ function divides(a::gfp_fmpz_elem, b::gfp_fmpz_elem)
return true, divexact(a, b)
end

###############################################################################
#
# Square root
#
###############################################################################

function Base.sqrt(a::gfp_fmpz_elem; check::Bool=true)
R = parent(a)
if iszero(a)
return zero(R)
end
z = fmpz()
flag = ccall((:fmpz_sqrtmod, libflint), Bool,
(Ref{fmpz}, Ref{fmpz}, Ref{fmpz}),
z, a.data, R.n)
check && !flag && error("Not a square in sqrt")
return gfp_fmpz_elem(z, R)
end

function issquare(a::gfp_fmpz_elem)
R = parent(a)
if iszero(a) || R.n == 2
return true
end
r = ccall((:fmpz_jacobi, libflint), Cint, (Ref{fmpz}, Ref{fmpz}),
a.data, R.n)
return isone(r)
end

function issquare_with_sqrt(a::gfp_fmpz_elem)
R = parent(a)
if iszero(a) || R.n == 2
return true, a
end
z = fmpz()
r = ccall((:fmpz_sqrtmod, libflint), Cint,
(Ref{fmpz}, Ref{fmpz}, Ref{fmpz}),
z, a.data, R.n)
if iszero(r)
return false, zero(R)
end
return true, gfp_fmpz_elem(z, R)
end

###############################################################################
#
# Unsafe functions
Expand Down
39 changes: 39 additions & 0 deletions test/flint/gfp_fmpz-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -474,3 +474,42 @@ end
end
end
end

@testset "gfp_fmpz.square_root" begin
for i = 1:100
p = rand(1:65537)
if Nemo.isprime(ZZ(p))
R = GF(ZZ(p))

z = rand(R)
if p != 2
while issquare(z)
z = rand(R)
end
end

for iter = 1:100
a = rand(R)

@test issquare(a^2)

s = sqrt(a^2)

@test s^2 == a^2

f1, s1 = issquare_with_sqrt(a^2)

@test f1 && s1^2 == a^2

if p != 2 && !iszero(a)
@test !issquare(z*a^2)

f2, s2 = issquare_with_sqrt(z*a^2)

@test !f2
end
end
end
end
end

0 comments on commit 011caf2

Please sign in to comment.