From b613c8af797a86c9867f569c4cc58de515f85e35 Mon Sep 17 00:00:00 2001 From: Sam HADOW Date: Tue, 6 Jan 2026 14:50:46 +0100 Subject: [PATCH] jacobi symbol --- ModularArithmeticUtils.hs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/ModularArithmeticUtils.hs b/ModularArithmeticUtils.hs index db0841e..0223439 100644 --- a/ModularArithmeticUtils.hs +++ b/ModularArithmeticUtils.hs @@ -25,3 +25,36 @@ factorOutTwos n = go n 0 go x s | even x = go (x `div` 2) (s + 1) | otherwise = (x, s) + +-- jacobi symbol (a/n) +-- (a/n) in {-1, 0, 1} +jacobi :: Integer -> Integer -> Integer +jacobi a n + | n <= 0 = error "jacobi: n must be positive" + | even n = error "jacobi: n must be odd" + | a `mod` n == 0 = 0 + | otherwise = go (a `mod` n) n 1 + where + go :: Integer -> Integer -> Integer -> Integer + go 0 _ _ = 0 + go 1 _ s = s + go x m s = + let (xOdd, e) = factorOutTwos x + s' = if even e then s else s * jacobi2 m + in + if xOdd == 1 + then s' + else + let s'' = if (xOdd `mod` 4 == 3) && (m `mod` 4 == 3) then -s' else s' + xNext = m `mod` xOdd + in go xNext xOdd s'' + +-- Jacobi(2, m), helper function +jacobi2 :: Integer -> Integer +jacobi2 m = + case m `mod` 8 of + 1 -> 1 + 7 -> 1 + 3 -> -1 + 5 -> -1 + _ -> error "jacobi2: unexpected (m mod 8) for odd m"