modular.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. use ibig::{ibig, modular::ModuloRing, ubig};
  2. #[test]
  3. fn test_modulus() {
  4. let ring = ModuloRing::new(&ubig!(100));
  5. assert_eq!(ring.modulus(), ubig!(100));
  6. let ring = ModuloRing::new(&ubig!(10).pow(100));
  7. assert_eq!(ring.modulus(), ubig!(10).pow(100));
  8. }
  9. #[test]
  10. fn test_clone() {
  11. let ring1 = ModuloRing::new(&ubig!(100));
  12. let x = ring1.from(512);
  13. let y = x.clone();
  14. assert_eq!(x, y);
  15. let mut z = ring1.from(513);
  16. assert_ne!(x, z);
  17. z.clone_from(&x);
  18. assert_eq!(x, z);
  19. let ring2 = ModuloRing::new(&ubig!(_1000000000000000000000000000000));
  20. let x = ring2.from(512);
  21. let y = x.clone();
  22. assert_eq!(x, y);
  23. let mut z = ring2.from(513);
  24. assert_ne!(x, z);
  25. z.clone_from(&x);
  26. assert_eq!(x, z);
  27. let mut x = ring1.from(512);
  28. let y = ring2.from(1);
  29. x.clone_from(&y);
  30. assert_eq!(x, y);
  31. let ring3 = ModuloRing::new(&ubig!(10).pow(100));
  32. let x = ring2.from(1);
  33. let mut y = ring3.from(2);
  34. y.clone_from(&x);
  35. assert_eq!(x, y);
  36. }
  37. #[test]
  38. fn test_convert() {
  39. let ring = ModuloRing::new(&ubig!(100));
  40. let x = ring.from(6);
  41. assert_eq!(x, ring.from(&ubig!(306)));
  42. assert_ne!(x, ring.from(&ubig!(313)));
  43. assert_eq!(x, ring.from(&ubig!(_18297381723918723981723981723906)));
  44. assert_ne!(x, ring.from(&ubig!(_18297381723918723981723981723913)));
  45. assert_eq!(x, ring.from(ubig!(_18297381723918723981723981723906)));
  46. assert_eq!(x, ring.from(ibig!(_18297381723918723981723981723906)));
  47. assert_eq!(x, ring.from(ibig!(-_18297381723918723981723981723994)));
  48. assert_eq!(x, ring.from(&ibig!(-_18297381723918723981723981723994)));
  49. assert_eq!(x, ring.from(106u8));
  50. assert_eq!(x, ring.from(106u16));
  51. assert_eq!(x, ring.from(1006u32));
  52. assert_eq!(x, ring.from(10000000006u64));
  53. assert_eq!(x, ring.from(1000000000000000000006u128));
  54. assert_eq!(x, ring.from(106usize));
  55. assert_eq!(x, ring.from(6i8));
  56. assert_eq!(x, ring.from(-94i8));
  57. assert_eq!(x, ring.from(-94i16));
  58. assert_eq!(x, ring.from(-94i32));
  59. assert_eq!(x, ring.from(-94i64));
  60. assert_eq!(x, ring.from(-94i128));
  61. assert_eq!(x, ring.from(-94isize));
  62. assert_eq!(ring.from(0), ring.from(false));
  63. assert_eq!(ring.from(1), ring.from(true));
  64. let ring = ModuloRing::new(&ubig!(
  65. _1000000000000000000000000000000000000000000000000000000000000
  66. ));
  67. let x = ring.from(6);
  68. let y = ring.from(ubig!(_333333333333333333333333333333));
  69. assert_eq!(
  70. x,
  71. ring.from(ubig!(
  72. _1000000000000000000000000000000000000000000000000000000000006
  73. ))
  74. );
  75. assert_eq!(
  76. x,
  77. ring.from(&ubig!(
  78. _1000000000000000000000000000000000000000000000000000000000006
  79. ))
  80. );
  81. assert_ne!(
  82. x,
  83. ring.from(ubig!(
  84. _1000000000000000000000000000000000000000000000000000000000007
  85. ))
  86. );
  87. assert_eq!(
  88. y,
  89. ring.from(ubig!(
  90. _7000000000000000000000000000000333333333333333333333333333333
  91. ))
  92. );
  93. }
  94. #[test]
  95. fn test_negate() {
  96. let ring = ModuloRing::new(&ubig!(100));
  97. let x = ring.from(-1234);
  98. let y = -&x;
  99. assert_eq!(y.residue(), ubig!(34));
  100. let y = -x;
  101. assert_eq!(y.residue(), ubig!(34));
  102. let ring = ModuloRing::new(&ubig!(_1000000000000000000000000000000));
  103. let x = ring.from(ibig!(-_33333123456789012345678901234567890));
  104. let y = -&x;
  105. assert_eq!(y, ring.from(ubig!(_44444123456789012345678901234567890)));
  106. assert_eq!(y.residue(), ubig!(_123456789012345678901234567890));
  107. let y = -x;
  108. assert_eq!(y, ring.from(ubig!(_44444123456789012345678901234567890)));
  109. }
  110. #[test]
  111. #[allow(clippy::eq_op)]
  112. fn test_different_rings() {
  113. let ring1 = ModuloRing::new(&ubig!(100));
  114. let ring2 = ModuloRing::new(&ubig!(100));
  115. assert_eq!(ring1, ring1);
  116. assert_ne!(ring1, ring2);
  117. }
  118. #[test]
  119. #[should_panic]
  120. fn test_cmp_different_rings() {
  121. let ring1 = ModuloRing::new(&ubig!(100));
  122. let ring2 = ModuloRing::new(&ubig!(200));
  123. let x = ring1.from(5);
  124. let y = ring2.from(5);
  125. let _ = x == y;
  126. }
  127. #[test]
  128. fn test_add_sub() {
  129. let ring1 = ModuloRing::new(&ubig!(100));
  130. let ring2 = ModuloRing::new(&ubig!(_1000000000000000000000000000000));
  131. let test_cases = [
  132. (ring1.from(1), ring1.from(2), ring1.from(3)),
  133. (ring1.from(99), ring1.from(5), ring1.from(4)),
  134. (ring1.from(99), ring1.from(99), ring1.from(98)),
  135. (
  136. ring2.from(ubig!(111111111111111111111111111111)),
  137. ring2.from(ubig!(222222222222222223333333333333)),
  138. ring2.from(ubig!(333333333333333334444444444444)),
  139. ),
  140. (
  141. ring2.from(ubig!(111111111111111111111111111111)),
  142. ring2.from(ubig!(888888888888888888888888888889)),
  143. ring2.from(ubig!(0)),
  144. ),
  145. (
  146. ring2.from(ubig!(999999999999999999999999999999)),
  147. ring2.from(ubig!(999999999999999999999999999997)),
  148. ring2.from(ubig!(999999999999999999999999999996)),
  149. ),
  150. ];
  151. let all_test_cases = test_cases
  152. .iter()
  153. .map(|(a, b, c)| (a, b, c))
  154. .chain(test_cases.iter().map(|(a, b, c)| (b, a, c)));
  155. for (a, b, c) in all_test_cases {
  156. assert_eq!(a + b, *c);
  157. assert_eq!(a.clone() + b, *c);
  158. assert_eq!(a + b.clone(), *c);
  159. assert_eq!(a.clone() + b.clone(), *c);
  160. let mut x = a.clone();
  161. x += b;
  162. assert_eq!(x, *c);
  163. let mut x = a.clone();
  164. x += b.clone();
  165. assert_eq!(x, *c);
  166. assert_eq!(c - a, *b);
  167. assert_eq!(c.clone() - a, *b);
  168. assert_eq!(c - a.clone(), *b);
  169. assert_eq!(c.clone() - a.clone(), *b);
  170. let mut x = c.clone();
  171. x -= a;
  172. assert_eq!(x, *b);
  173. let mut x = c.clone();
  174. x -= a.clone();
  175. assert_eq!(x, *b);
  176. }
  177. }
  178. #[test]
  179. fn test_mul() {
  180. let ring1 = ModuloRing::new(&ubig!(100));
  181. let ring2 = ModuloRing::new(&ubig!(_1000000000000000000000000000000));
  182. let big = ubig!(10).pow(10000);
  183. let ring3 = ModuloRing::new(&big);
  184. let test_cases = [
  185. (ring1.from(23), ring1.from(96), ring1.from(8)),
  186. (
  187. ring2.from(ubig!(_46301564276035228370597101114)),
  188. ring2.from(ubig!(_170100953649249045221461413048)),
  189. ring2.from(ubig!(_399394418012748758198974935472)),
  190. ),
  191. (
  192. ring3.from(&big - ubig!(1)),
  193. ring3.from(&big - ubig!(1)),
  194. ring3.from(1),
  195. ),
  196. ];
  197. let all_test_cases = test_cases
  198. .iter()
  199. .map(|(a, b, c)| (a, b, c))
  200. .chain(test_cases.iter().map(|(a, b, c)| (b, a, c)));
  201. for (a, b, c) in all_test_cases {
  202. assert_eq!(a * b, *c);
  203. assert_eq!(a.clone() * b, *c);
  204. assert_eq!(a * b.clone(), *c);
  205. assert_eq!(a.clone() * b.clone(), *c);
  206. let mut x = a.clone();
  207. x *= b;
  208. assert_eq!(x, *c);
  209. let mut x = a.clone();
  210. x *= b.clone();
  211. assert_eq!(x, *c);
  212. }
  213. }
  214. #[test]
  215. fn test_inverse() {
  216. let ring = ModuloRing::new(&ubig!(1));
  217. assert_eq!(ring.from(0).inverse(), Some(ring.from(0)));
  218. let ring = ModuloRing::new(&ubig!(100));
  219. let x = ring.from(9);
  220. let y = x.inverse().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  221. assert_eq!(x * y, ring.from(1));
  222. assert!(ring.from(10).inverse().is_none());
  223. let ring = ModuloRing::new(&ubig!(103));
  224. assert_eq!(ring.from(20).inverse(), Some(ring.from(67))); // inverse is unique for prime modulus
  225. let ring = ModuloRing::new(&ubig!(1000000000000000000000000000000));
  226. let x = ring.from(ibig!(3333312345678901234567890123456789));
  227. let y = x.inverse().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  228. assert_eq!(x * y, ring.from(1));
  229. assert!(ring.from(10).inverse().is_none());
  230. let ring = ModuloRing::new(&ubig!(1000000000000000000000000000057)); // prime
  231. assert_eq!(
  232. ring.from(123456789).inverse(),
  233. Some(ring.from(ubig!(951144331155413413514262063034)))
  234. );
  235. }
  236. #[test]
  237. fn test_div() {
  238. let ring = ModuloRing::new(&ubig!(1));
  239. assert_eq!(ring.from(0) / ring.from(0), ring.from(0));
  240. let ring = ModuloRing::new(&ubig!(10));
  241. // 2 / 3 == 4
  242. let a = ring.from(2);
  243. let b = ring.from(3);
  244. let res = ring.from(4);
  245. assert_eq!(a.clone() / b.clone(), res);
  246. assert_eq!(a.clone() / &b, res);
  247. assert_eq!(&a / b.clone(), res);
  248. assert_eq!(&a / &b, res);
  249. let mut a = ring.from(2);
  250. a /= b.clone();
  251. assert_eq!(a, res);
  252. let mut a = ring.from(2);
  253. a /= &b;
  254. assert_eq!(a, res);
  255. }
  256. #[test]
  257. #[should_panic]
  258. fn test_add_different_rings() {
  259. let ring1 = ModuloRing::new(&ubig!(100));
  260. let ring2 = ModuloRing::new(&ubig!(200));
  261. let x = ring1.from(5);
  262. let y = ring2.from(5);
  263. let _ = x + y;
  264. }
  265. #[test]
  266. #[should_panic]
  267. fn test_sub_different_rings() {
  268. let ring1 = ModuloRing::new(&ubig!(100));
  269. let ring2 = ModuloRing::new(&ubig!(200));
  270. let x = ring1.from(5);
  271. let y = ring2.from(5);
  272. let _ = x - y;
  273. }
  274. #[test]
  275. #[should_panic]
  276. fn test_mul_different_rings() {
  277. let ring1 = ModuloRing::new(&ubig!(100));
  278. let ring2 = ModuloRing::new(&ubig!(200));
  279. let x = ring1.from(5);
  280. let y = ring2.from(5);
  281. let _ = x * y;
  282. }
  283. #[test]
  284. #[should_panic]
  285. fn test_div_different_rings() {
  286. let ring1 = ModuloRing::new(&ubig!(100));
  287. let ring2 = ModuloRing::new(&ubig!(200));
  288. let x = ring1.from(1);
  289. let y = ring2.from(1);
  290. let _ = x / y;
  291. }
  292. #[test]
  293. #[should_panic]
  294. fn test_div_by_noninvertible() {
  295. let ring = ModuloRing::new(&ubig!(100));
  296. let x = ring.from(10);
  297. let y = ring.from(2);
  298. let _ = x / y;
  299. }
  300. #[test]
  301. fn test_pow() {
  302. let ring = ModuloRing::new(&ubig!(100));
  303. assert_eq!(ring.from(0).pow(&ubig!(0)), ring.from(1));
  304. assert_eq!(ring.from(13).pow(&ubig!(0)), ring.from(1));
  305. assert_eq!(ring.from(13).pow(&ubig!(1)), ring.from(13));
  306. assert_eq!(ring.from(13).pow(&ubig!(2)), ring.from(69));
  307. assert_eq!(ring.from(13).pow(&ubig!(12837918273)), ring.from(53));
  308. assert_eq!(
  309. ring.from(13)
  310. .pow(&((ubig!(1) << 10000) * ubig!(40) + ubig!(3))),
  311. ring.from(97)
  312. );
  313. let ring = ModuloRing::new(&ubig!(_1000000000000000000000000000000));
  314. let x = ring.from(ubig!(_658571505947767552546868380533));
  315. assert_eq!(x.pow(&ubig!(0)), ring.from(1));
  316. assert_eq!(x.pow(&ubig!(1)), x);
  317. assert_eq!(
  318. x.pow(&ubig!(_794990856522773482558337459018)),
  319. ring.from(ubig!(_660533815789733011052086421209))
  320. );
  321. // A Mersenne prime.
  322. let prime = ubig!(2).pow(4423) - ubig!(1);
  323. let ring = ModuloRing::new(&prime);
  324. // Fermat theorem: a^(p-1) = 1
  325. assert_eq!(ring.from(13).pow(&(prime - ubig!(1))), ring.from(1));
  326. }
  327. #[test]
  328. fn test_pow_signed() {
  329. let ring = ModuloRing::new(&ubig!(100));
  330. assert_eq!(ring.from(2).pow_signed(&ibig!(10)), ring.from(24));
  331. assert_eq!(ring.from(3).pow_signed(&ibig!(-3)), ring.from(63));
  332. }
  333. #[test]
  334. #[should_panic]
  335. fn test_pow_signed_noninvertible() {
  336. let ring = ModuloRing::new(&ubig!(100));
  337. let _ = ring.from(2).pow_signed(&ibig!(-2));
  338. }
  339. #[test]
  340. fn test_format() {
  341. let ring = ModuloRing::new(&ubig!(100));
  342. let x = ring.from(105);
  343. assert_eq!(format!("{}", ring), "mod 100");
  344. assert_eq!(format!("{}", x), "5 (mod 100)");
  345. assert_eq!(format!("{:?}", x), "5 (mod 100)");
  346. assert_eq!(format!("{:=^5}", x), "==5== (mod =100=)");
  347. assert_eq!(format!("{:b}", x), "101 (mod 1100100)");
  348. assert_eq!(format!("{:o}", x), "5 (mod 144)");
  349. assert_eq!(format!("{:#x}", x), "0x5 (mod 0x64)");
  350. assert_eq!(format!("{:X}", x), "5 (mod 64)");
  351. let ring = ModuloRing::new(&ubig!(_1000000000000000000000000000000));
  352. let x = -ring.from(1);
  353. assert_eq!(format!("{}", ring), "mod 1000000000000000000000000000000");
  354. assert_eq!(
  355. format!("{:?}", x),
  356. "999999999999999999999999999999 (mod 1000000000000000000000000000000)"
  357. );
  358. assert_eq!(
  359. format!("{:35}", x),
  360. " 999999999999999999999999999999 (mod 1000000000000000000000000000000)"
  361. );
  362. assert_eq!(format!("{:b}", x),
  363. "1100100111110010110010011100110100000100011001110100111011011110101000111111111111111111111111111111 (mod 1100100111110010110010011100110100000100011001110100111011011110101001000000000000000000000000000000)");
  364. assert_eq!(
  365. format!("{:#o}", x),
  366. "0o1447626234640431647336507777777777 (mod 0o1447626234640431647336510000000000)"
  367. );
  368. assert_eq!(
  369. format!("{:x}", x),
  370. "c9f2c9cd04674edea3fffffff (mod c9f2c9cd04674edea40000000)"
  371. );
  372. assert_eq!(
  373. format!("{:X}", x),
  374. "C9F2C9CD04674EDEA3FFFFFFF (mod C9F2C9CD04674EDEA40000000)"
  375. );
  376. }