Skip to content

Commit

Permalink
feat: add rho-Pollard example (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
vil02 authored Sep 22, 2023
1 parent 38eb846 commit 9313635
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions examples/pollard_rho.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## Pollard's rho algorithm
##
## This file illustrates how to find a factor of an integer using
## [Pollard's rho algorithm](https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm).

import bigints
import std/options
import std/strformat


func pollardRho(
n: BigInt,
polynomial: proc(x: BigInt): BigInt {.noSideEffect.},
initialValue: BigInt = 2.initBigInt): Option[BigInt] =
## Performs Pollard's rho algorithm to find a non-trivial factor of `n`.
func polynomialMod(x: BigInt): BigInt =
polynomial(x) mod n

var
turtle = initialValue
hare = initialValue
divisor = 1.initBigInt

while divisor == 1.initBigInt:
turtle = polynomialMod(turtle)
hare = polynomialMod(polynomialMod(hare))
divisor = gcd(turtle - hare, n)

if divisor != n:
some(divisor)
else:
none(BigInt)


func somePolynomial(x: BigInt): BigInt =
x * x + 1.initBigInt


proc main() =
const someNum = "44077431694086786329".initBigInt
let result = pollardRho(someNum, somePolynomial)
if result.isSome():
let factor = result.get()
echo fmt"{factor} is a factor of {someNum}"
assert someNum mod factor == 0.initBigInt
else:
echo fmt"could not find a factor of {someNum}"


main()

0 comments on commit 9313635

Please sign in to comment.