How to resolve the algorithm Tonelli-Shanks algorithm step by step in the Julia programming language

Published on 22 June 2024 08:30 PM

How to resolve the algorithm Tonelli-Shanks algorithm step by step in the Julia programming language

Table of Contents

Problem Statement

In computational number theory, the Tonelli–Shanks algorithm is a technique for solving for x in a congruence of the form:

where n is an integer which is a quadratic residue (mod p), p is an odd prime, and x,n ∈ Fp where Fp = {0, 1, ..., p - 1}. It is used in cryptography techniques.

To apply the algorithm, we need the Legendre symbol: The Legendre symbol (a | p) denotes the value of a(p-1)/2 (mod p).

All ≡ are taken to mean (mod p) unless stated otherwise.

Implement the above algorithm. Find solutions (if any) for

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Tonelli-Shanks algorithm step by step in the Julia programming language

The Julia code implements Tonelli-Shanks algorithm to find square roots modulo a prime number.

The Tonelli-Shanks algorithm is an algorithm for computing square roots modulo a prime number. Given a prime number p and an integer n, the algorithm computes an integer x such that x^2 ≡ n (mod p).

The algorithm works by first checking if n is a square modulo p. If it is not, then the algorithm fails. Otherwise, the algorithm proceeds as follows:

  1. Find the smallest integer s such that 2^s ≡ p-1 (mod p).
  2. Set z to an integer such that z^2 ≡ n (mod p).
  3. Set c to z^q, where q is the quotient of p-1 by 2^s.
  4. Set r to n^(q+1)/2 (mod p).
  5. Set t to n^q (mod p).
  6. Set m to s.
  7. While t-1 is not divisible by p, do the following:
    • Set t2 to t^2 (mod p).
    • Set i to the smallest integer such that t2-1 is divisible by p.
    • Set b to c^(1 << (m-i-1)) (mod p).
    • Set r to r * b (mod p).
    • Set c to b^2 (mod p).
    • Set t to t * c (mod p).
    • Set m to i.
  8. Return r and p-r.

The Julia code implements the above algorithm in the solve function. The solve function takes two arguments: n, the integer for which we want to find a square root modulo p, and p, the prime modulus. The function returns a tuple of two integers, r and p-r, such that r^2 ≡ n (mod p) and (p-r)^2 ≡ n (mod p).

The code also includes some examples of how to use the solve function. The following is the output of the code:

julia> @show TonelliShanks.solve(10, 13)
(2, 11)

julia> @show TonelliShanks.solve(56, 101)
(7, 94)

julia> @show TonelliShanks.solve(1030, 10009)
(3203, 6806)

julia> @show TonelliShanks.solve(44402, 100049)
(99989, 1016)

julia> @show TonelliShanks.solve(665820697, 1000000009)
(63179448, 936820521)

julia> @show TonelliShanks.solve(881398088036, 1000000000039)
(50238433523, 497615664816)

julia> @show TonelliShanks.solve(41660815127637347468140745042827704103445750172002, big"10" ^ 50 + 577)
(91323883417214063027396207738225853139832544869471, 90867611658278593697260389226177414686016745513051)

Source code in the julia programming language

module TonelliShanks

legendre(a, p) = powermod(a, (p - 1) ÷ 2, p)

function solve(n::T, p::T) where T <: Union{Int, Int128, BigInt}
    legendre(n, p) != 1 && throw(ArgumentError("$n not a square (mod $p)"))
    local q::T = p - one(p)
    local s::T = 0
    while iszero(q % 2)
        q ÷= 2
        s += one(s)
    end
    if s == one(s)
        r = powermod(n, (p + 1) >> 2, p)
        return r, p - r
    end
    local z::T
    for z in 2:(p - 1)
        p - 1 == legendre(z, p) && break
    end
    local c::T = powermod(z, q, p)
    local r::T = powermod(n, (q + 1) >> 1, p)
    local t::T = powermod(n, q, p)
    local m::T = s
    local t2::T = zero(p)
    while !iszero((t - 1) % p)
        t2 = (t * t) % p
        local i::T
        for i in Base.OneTo(m)
            iszero((t2 - 1) % p) && break
            t2 = (t2 * t2) % p
        end
        b = powermod(c, 1 << (m - i - 1), p)
        r = (r * b) % p
        c = (b * b) % p
        t = (t * c) % p
        m = i
    end
    return r, p - r
end

end  # module TonelliShanks


@show TonelliShanks.solve(10, 13)
@show TonelliShanks.solve(56, 101)
@show TonelliShanks.solve(1030, 10009)
@show TonelliShanks.solve(44402, 100049)
@show TonelliShanks.solve(665820697, 1000000009)
@show TonelliShanks.solve(881398088036, 1000000000039)
@show TonelliShanks.solve(41660815127637347468140745042827704103445750172002, big"10" ^ 50 + 577)


  

You may also check:How to resolve the algorithm Matrix multiplication step by step in the ooRexx programming language
You may also check:How to resolve the algorithm Table creation/Postal addresses step by step in the Lua programming language
You may also check:How to resolve the algorithm User input/Graphical step by step in the Nanoquery programming language
You may also check:How to resolve the algorithm Unbias a random generator step by step in the Wren programming language
You may also check:How to resolve the algorithm CSV data manipulation step by step in the BASIC programming language