-USING: kernel math sequences namespaces
-math.miller-rabin combinators.lib
-math.functions accessors random ;
+USING: accessors kernel math math.functions math.primes random ;
IN: random.blum-blum-shub
-! TODO: take (log log M) bits instead of 1 bit
-! Blum Blum Shub, M = pq
+! Blum Blum Shub, n = pq, x_i+1 = x_i ^ 2 mod n
+! return low bit of x+1
TUPLE: blum-blum-shub x n ;
-C: <blum-blum-shub> blum-blum-shub
+<PRIVATE
+
+: generate-bbs-prime ( numbits -- p )
+ dup random-prime dup 4 mod 3 =
+ [ nip ] [ drop generate-bbs-prime ] if ;
: generate-bbs-primes ( numbits -- p q )
- #! two primes congruent to 3 (mod 4)
- [ [ random-prime ] curry [ 4 mod 3 = ] generate ] dup bi ;
+ [ generate-bbs-prime ] [ generate-bbs-prime ] bi ;
+
+: next-bbs-bit ( bbs -- bit )
+ dup [ x>> 2 ] [ n>> ] bi ^mod [ >>x drop ] [ 1 bitand ] bi ;
+
+PRIVATE>
-IN: crypto
: <blum-blum-shub> ( numbits -- blum-blum-shub )
- #! returns a Blum-Blum-Shub tuple
generate-bbs-primes *
[ find-relative-prime ] keep
- blum-blum-shub construct-boa ;
-
-! 256 make-bbs blum-blum-shub set-global
-
-: next-bbs-bit ( bbs -- bit )
- #! x = x^2 mod n, return low bit of calculated x
- [ [ x>> 2 ] [ n>> ] bi ^mod ]
- [ [ >>x ] keep x>> 1 bitand ] bi ;
-
-IN: crypto
-! : random ( n -- n )
- ! ! #! Cryptographically secure random number using Blum-Blum-Shub 256
- ! [ log2 1+ random-bits ] keep dupd >= [ -1 shift ] when ;
+ blum-blum-shub boa ;
-M: blum-blum-shub random-32* ( bbs -- r )
- ;
+M: blum-blum-shub random-32*
+ 0 32 rot
+ [ next-bbs-bit swap 1 shift bitor ] curry times ;