factor/contrib/crypto/miller-rabin.factor

62 lines
1.7 KiB
Factor

USING: kernel math errors namespaces math-contrib sequences io ;
USE: prettyprint
USE: inspector
IN: crypto
SYMBOL: a
SYMBOL: n
SYMBOL: r
SYMBOL: s
SYMBOL: composite
SYMBOL: count
SYMBOL: trials
: rand[1..n-1] ( n -- )
1- random-int 1+ ;
: (factor-2s) ( s n -- s n )
dup 2 mod 0 = [ -1 shift >r 1+ r> (factor-2s) ] when ;
: factor-2s ( n -- r s )
#! factor an even number into 2 ^ s * m
dup dup even? >r 0 > r> and [
"input must be positive and even" throw
] unless 0 swap (factor-2s) ;
: init-miller-rabin ( n -- )
0 composite set
[ n set ] keep 10000 < 20 100 ? trials set ;
: miller-rabin ( n -- bool )
[
init-miller-rabin
n get even? [
f ] [
n get 1- factor-2s s set r set
trials get [
n get rand[1..n-1] a set
a get s get n get ^mod 1 = [
0 count set
r get [
2 over ^ s get * a get swap n get ^mod n get - -1 = [
count [ 1+ ] change
r get +
] when
] repeat
count get zero? [
composite on
trials get +
] when
] unless
] repeat
composite get 0 = [ t ] [ composite get not ] if
] if
] with-scope ;
: next-miller-rabin-prime ( n -- p )
dup even? [ 1+ ] [ 2 + ] if
dup miller-rabin [ next-miller-rabin-prime ] unless ;
! 473155932665450549999756893736999469773678960651272093993257221235459777950185377130233556540099119926369437865330559863 100 miller-rabin