Skip to content

Commit

Permalink
Implemented the Chinese Remainder Theorem
Browse files Browse the repository at this point in the history
  • Loading branch information
ghuysmans committed Aug 23, 2019
1 parent 3572071 commit 9f21f4b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 2 deletions.
25 changes: 25 additions & 0 deletions bin/chinese.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
open Toy_crypto
module M = Numbers.Make (Int) (* FIXME *)

open Printf


let () =
let int_arg n = int_of_string Sys.argv.(n) in
if Array.length Sys.argv = 5 then
let a, p, b, q = int_arg 1, int_arg 2, int_arg 3, int_arg 4 in
printf "Input problem:\n\tx = %d mod %d\n\tx = %d mod %d\n" a p b q;
try
let n = M.crt (a, p) (b, q) in
printf "Solution:\n\tx = %d mod %d\n" n (p * q)
with Failure _ ->
printf "No solution:\n\t%d and %d aren't coprime.\n" p q
else
let p, q = int_arg 1, int_arg 2 in
printf "(a, b) represents this:\n\tx = a mod %d\n\tx = b mod %d\n" p q;
for a=0 to p-1 do
for b=0 to q-1 do
let n = M.crt (a, p) (b, q) in
printf "(%d, %d) -> %d\n" a b n
done
done
4 changes: 2 additions & 2 deletions bin/dune
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(executable
(name main)
(executables
(names main chinese)
(libraries toy_crypto))
(install
(section bin)
Expand Down
7 changes: 7 additions & 0 deletions lib/numbers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module type S = sig
val euclid: N.t -> N.t -> e
val gcd: N.t -> N.t -> N.t
val inv: N.t -> m:N.t -> N.t
val crt: N.t * N.t -> N.t * N.t -> N.t
val random: bits:int -> N.t
val random_prime: bits:int -> N.t
val of_string : string -> N.t
Expand Down Expand Up @@ -102,6 +103,12 @@ module Make (N: Concrete) = struct
(* this should not happen *)
failwith "non-invertible value"

let crt (a, p) (b, q) =
let open N in
let p1, q1 = inv p ~m:q, inv q ~m:p in
let n = (a * q1 * q + b * p1 * p) mod (p * q) in
if n < zero then n + p * q else n

let random ~bits =
let rec f a = function
| 0 -> a
Expand Down
3 changes: 3 additions & 0 deletions lib/numbers.mli
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ module type S = sig

val gcd: N.t -> N.t -> N.t
val inv: N.t -> m:N.t -> N.t
val crt: N.t * N.t -> N.t * N.t -> N.t
(* [crt (a, p) (b, q)] solves ${x = a mod p, x = b mod q}$ *)

val random: bits:int -> N.t
val random_prime: bits:int -> N.t
val of_string : string -> N.t
Expand Down

0 comments on commit 9f21f4b

Please sign in to comment.