You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

420 lines
11 KiB

4 years ago
  1. use crate::{Fq, Fr};
  2. use ark_ff::{
  3. biginteger::BigInteger256 as BigInteger,
  4. bytes::{FromBytes, ToBytes},
  5. fields::{Field, LegendreSymbol::*, SquareRootField},
  6. test_rng, One, Zero,
  7. };
  8. use ark_curve_tests::fields::*;
  9. use core::str::FromStr;
  10. use rand::Rng;
  11. #[test]
  12. fn test_fr() {
  13. let mut rng = test_rng();
  14. let a: Fr = rng.gen();
  15. let b: Fr = rng.gen();
  16. field_test(a, b);
  17. primefield_test::<Fr>();
  18. }
  19. #[test]
  20. fn test_fq() {
  21. let mut rng = test_rng();
  22. let a: Fq = rng.gen();
  23. let b: Fq = rng.gen();
  24. field_test(a, b);
  25. primefield_test::<Fq>();
  26. }
  27. #[test]
  28. fn test_fq_add() {
  29. let f1 = Fq::from_str(
  30. "18386742314266644595564329008376577163854043021652781768352795308532764650733",
  31. )
  32. .unwrap();
  33. let f2 = Fq::from_str(
  34. "39786307610986038981023499868190793548353538256264351797285876981647142458383",
  35. )
  36. .unwrap();
  37. let f3 = Fq::from_str(
  38. "14396564181574133132095017386052820535110852477085064878242263917028290117882",
  39. )
  40. .unwrap();
  41. assert!(!f1.is_zero());
  42. assert!(!f2.is_zero());
  43. assert!(!f3.is_zero());
  44. assert_eq!(f1 + &f2, f3);
  45. }
  46. #[test]
  47. fn test_fq_add_one() {
  48. let f1 = Fq::from_str(
  49. "4946875394261337176810256604189376311946643975348516311606738923340201185904",
  50. )
  51. .unwrap();
  52. let f2 = Fq::from_str(
  53. "4946875394261337176810256604189376311946643975348516311606738923340201185905",
  54. )
  55. .unwrap();
  56. assert!(!f1.is_zero());
  57. assert!(!f2.is_zero());
  58. assert_eq!(f1 + &Fq::one(), f2);
  59. }
  60. #[test]
  61. fn test_fq_mul() {
  62. let f1 = Fq::from_str(
  63. "24703123148064348394273033316595937198355721297494556079070134653139656190956",
  64. )
  65. .unwrap();
  66. let f2 = Fq::from_str(
  67. "38196797080882758914424853878212529985425118523754343117256179679117054302131",
  68. )
  69. .unwrap();
  70. let f3 = Fq::from_str(
  71. "1321267396236123309645330145349353750536542060403774171357889269349508194307",
  72. )
  73. .unwrap();
  74. assert!(!f1.is_zero());
  75. assert!(!f2.is_zero());
  76. assert!(!f3.is_zero());
  77. assert_eq!(f1 * &f2, f3);
  78. }
  79. #[test]
  80. fn test_fq_triple_mul() {
  81. let f1 = Fq::from_str(
  82. "23834398828139479510988224171342199299644042568628082836691700490363123893905",
  83. )
  84. .unwrap();
  85. let f2 = Fq::from_str(
  86. "48343809612844640454129919255697536258606705076971130519928764925719046689317",
  87. )
  88. .unwrap();
  89. let f3 = Fq::from_str(
  90. "22704845471524346880579660022678666462201713488283356385810726260959369106033",
  91. )
  92. .unwrap();
  93. let f4 = Fq::from_str(
  94. "7747776931431194635550680695131420638163057297019399136408144301550822179875",
  95. )
  96. .unwrap();
  97. assert!(!f1.is_zero());
  98. assert!(!f2.is_zero());
  99. assert!(!f3.is_zero());
  100. assert_eq!(f1 * &f2 * &f3, f4);
  101. }
  102. #[test]
  103. fn test_fq_div() {
  104. let f1 = Fq::from_str(
  105. "31892744363926593013886463524057935370302352424137349660481695792871889573091",
  106. )
  107. .unwrap();
  108. let f2 = Fq::from_str(
  109. "47695868328933459965610498875668250916462767196500056002116961816137113470902",
  110. )
  111. .unwrap();
  112. let f3 = Fq::from_str(
  113. "7301086967624450577859019086314322648061398679982346993011603220910508457334",
  114. )
  115. .unwrap();
  116. assert!(!f1.is_zero());
  117. assert!(!f2.is_zero());
  118. assert!(!f3.is_zero());
  119. assert_eq!(f1 / &f2, f3);
  120. }
  121. #[test]
  122. fn test_fq_sub() {
  123. let f1 = Fq::from_str(
  124. "18695869713129401390241150743745601908470616448391638969502807001833388904079",
  125. )
  126. .unwrap();
  127. let f2 = Fq::from_str(
  128. "10105476028534616828778879109836101003805485072436929139123765141153277007373",
  129. )
  130. .unwrap();
  131. let f3 = Fq::from_str(
  132. "8590393684594784561462271633909500904665131375954709830379041860680111896706",
  133. )
  134. .unwrap();
  135. assert!(!f1.is_zero());
  136. assert!(!f2.is_zero());
  137. assert!(!f3.is_zero());
  138. assert_eq!(f1 - &f2, f3);
  139. }
  140. #[test]
  141. fn test_fq_double_in_place() {
  142. let mut f1 = Fq::from_str(
  143. "29729289787452206300641229002276778748586801323231253291984198106063944136114",
  144. )
  145. .unwrap();
  146. let f3 = Fq::from_str(
  147. "15682093831225862156789646514039007320076873845630437896571987838976271280994",
  148. )
  149. .unwrap();
  150. assert!(!f1.is_zero());
  151. assert!(!f3.is_zero());
  152. f1.double_in_place();
  153. assert_eq!(f1, f3);
  154. }
  155. #[test]
  156. fn test_fq_double_in_place_thrice() {
  157. let mut f1 = Fq::from_str(
  158. "32768907806651393940832831055386272949401004221411141755415956893066040832473",
  159. )
  160. .unwrap();
  161. let f3 = Fq::from_str(
  162. "21380590862979124081952185245260157621176025366712756262647409092194433207997",
  163. )
  164. .unwrap();
  165. assert!(!f1.is_zero());
  166. assert!(!f3.is_zero());
  167. f1.double_in_place();
  168. f1.double_in_place();
  169. f1.double_in_place();
  170. assert_eq!(f1, f3);
  171. }
  172. #[test]
  173. fn test_fq_generate_random_ed_on_bn254_point() {
  174. let a = Fq::from_str("168700").unwrap();
  175. let d = Fq::from_str("168696").unwrap();
  176. let y = Fq::from_str(
  177. "19987327827845206670850937090314462639017692512983955920885166014935289314257",
  178. )
  179. .unwrap();
  180. let x2 = Fq::from_str(
  181. "2144239075372598103060889495211040948751593385312551803225522963913923559328",
  182. )
  183. .unwrap();
  184. let computed_y2 = y.square();
  185. let y2 = Fq::from_str(
  186. "11134206686211572308995578277928848431421308813024790181507137950838333998633",
  187. )
  188. .unwrap();
  189. assert_eq!(y2, computed_y2);
  190. let computed_dy2 = d * &computed_y2;
  191. let dy2 =
  192. Fq::from_str("345576003677591687256955722467813448317229128849323754147891993737799010947")
  193. .unwrap();
  194. assert_eq!(dy2, computed_dy2);
  195. let computed_divisor = computed_dy2 - a;
  196. let divisor =
  197. Fq::from_str("345576003677591687256955722467813448317229128849323754147891993737798842247")
  198. .unwrap();
  199. assert_eq!(divisor, computed_divisor);
  200. let computed_x2 = (computed_y2 - &Fq::one()) / &computed_divisor;
  201. assert_eq!(x2, computed_x2);
  202. let x = Fq::from_str(
  203. "4801447892755635304907919953550459075619191823587157449340656925102682829025",
  204. )
  205. .unwrap();
  206. let computed_x = computed_x2.sqrt().unwrap();
  207. assert_eq!(computed_x.square(), x2);
  208. assert_eq!(x, computed_x);
  209. fn add<'a>(curr: (Fq, Fq), other: &'a (Fq, Fq)) -> (Fq, Fq) {
  210. let y1y2 = curr.1 * &other.1;
  211. let x1x2 = curr.0 * &other.0;
  212. let a = Fq::from_str("168700").unwrap();
  213. let d = Fq::from_str("168696").unwrap();
  214. let dx1x2y1y2 = d * &y1y2 * &x1x2;
  215. let d1 = Fq::one() + &dx1x2y1y2;
  216. let d2 = Fq::one() - &dx1x2y1y2;
  217. let x1y2 = curr.0 * &other.1;
  218. let y1x2 = curr.1 * &other.0;
  219. let x = (x1y2 + &y1x2) / &d1;
  220. let y = (y1y2 - a * &x1x2) / &d2;
  221. (x, y)
  222. }
  223. let result = add((x, y), &(x, y));
  224. let result = add(result, &result);
  225. let result = add(result, &result);
  226. let point_x =
  227. Fq::from_str("380676173762867192861894055350059333852732198308367125138259398265363727587")
  228. .unwrap();
  229. let point_y = Fq::from_str(
  230. "8435074244857818446059206728316702149733931432112984450960434710303841866985",
  231. )
  232. .unwrap();
  233. assert_eq!((point_x, point_y), result);
  234. }
  235. #[test]
  236. fn test_fq_square_in_place() {
  237. let mut f1 = Fq::from_str(
  238. "6060110850233386730847324622937480088943976359504617699731744947670229990461",
  239. )
  240. .unwrap();
  241. let f3 = Fq::from_str(
  242. "17018926051730832095053393285350575966874590491719897015583930476179087429684",
  243. )
  244. .unwrap();
  245. assert!(!f1.is_zero());
  246. assert!(!f3.is_zero());
  247. f1.square_in_place();
  248. assert_eq!(f1, f3);
  249. }
  250. #[test]
  251. fn test_fq_sqrt() {
  252. let f1 = Fq::from_str(
  253. "5830207146824777307592559303161432403393380070279905260050870500920682305217",
  254. )
  255. .unwrap();
  256. let f3 = Fq::from_str(
  257. "2108183130040740552565127577293974960058698876185401671087892009247563211475",
  258. )
  259. .unwrap();
  260. assert_eq!(f1.sqrt().unwrap(), f3);
  261. }
  262. #[test]
  263. fn test_fq_from_str() {
  264. let f1_from_repr = Fq::from(BigInteger([
  265. 0xab8a2535947d1a77,
  266. 0x9ba74cbfda0bbcda,
  267. 0xe928b59724d60baf,
  268. 0x1cccaaeb9bb1680a,
  269. ]));
  270. let f1 = Fq::from_str(
  271. "13026376210409056429264774981357153555336288129100724591327877625017068755575",
  272. )
  273. .unwrap();
  274. let f2_from_repr = Fq::from(BigInteger([
  275. 0x97e9103775d2f35c,
  276. 0xbe6756b6c587544b,
  277. 0x6ee38c3afd88ef4b,
  278. 0x2bacd150f540c677,
  279. ]));
  280. let f2 = Fq::from_str(
  281. "19754794831832707859764530223239420866832328728734160755396495950822165902172",
  282. )
  283. .unwrap();
  284. assert_eq!(f1_from_repr, f1);
  285. assert_eq!(f2_from_repr, f2);
  286. }
  287. #[test]
  288. fn test_fq_legendre() {
  289. assert_eq!(QuadraticResidue, Fq::one().legendre());
  290. assert_eq!(Zero, Fq::zero().legendre());
  291. let e = BigInteger([
  292. 0x2e8de1a676c03be8,
  293. 0x73350d34fe25a560,
  294. 0x7ea085919029688e,
  295. 0x1d0868cb993cf28,
  296. ]);
  297. assert_eq!(QuadraticResidue, Fq::from(e).legendre());
  298. let e = BigInteger([
  299. 0x891d8cc23c8d0706,
  300. 0xe91800e007db2698,
  301. 0xfff380321e9ac7a7,
  302. 0x2659e28bd17eab6,
  303. ]);
  304. assert_eq!(QuadraticNonResidue, Fq::from(e).legendre());
  305. }
  306. #[test]
  307. fn test_fq_bytes() {
  308. let f1_from_repr = Fq::from(BigInteger([
  309. 0xab8a2535947d1a77,
  310. 0x9ba74cbfda0bbcda,
  311. 0xe928b59724d60baf,
  312. 0x1cccaaeb9bb1680a,
  313. ]));
  314. let mut f1_bytes = [0u8; 32];
  315. f1_from_repr.write(f1_bytes.as_mut()).unwrap();
  316. let f1 = Fq::read(f1_bytes.as_ref()).unwrap();
  317. assert_eq!(f1_from_repr, f1);
  318. }
  319. #[test]
  320. fn test_fr_add() {
  321. let f1 = Fr::from(BigInteger([
  322. 0xccfc9a195e0f5c46,
  323. 0xaed4874d13fb1285,
  324. 0x27368f86ca2848eb,
  325. 0x4f8adcfeb44fccc,
  326. ]));
  327. let f2 = Fr::from(BigInteger([
  328. 0x661ff05bf8570851,
  329. 0x1b171f4c59be97ef,
  330. 0x5d2ce7f9b4d701f3,
  331. 0x1e0e794623e0f68,
  332. ]));
  333. let f3 = Fr::from(BigInteger([
  334. 0xcba9f2991d453da6,
  335. 0x1eacb8e13498bc6a,
  336. 0x4d596ec9aecf1fd3,
  337. 0xcd0b95f15cd82f,
  338. ]));
  339. assert_eq!(f1 + &f2, f3);
  340. }
  341. #[test]
  342. fn test_fr_mul() {
  343. let f1 = Fr::from(BigInteger([
  344. 0xc2964d2dd5fb980f,
  345. 0xbab64d599c57e496,
  346. 0x39cae13e7d1d4f78,
  347. 0x1aa995aa4de205c,
  348. ]));
  349. let f2 = Fr::from(BigInteger([
  350. 0xc256e720cd43533b,
  351. 0x3bfbadf6247e13bb,
  352. 0x94c3d63a53714f63,
  353. 0x10f8a7bf74efd57,
  354. ]));
  355. let f3 = Fr::from(BigInteger([
  356. 0x5eac88be41e0e1fd,
  357. 0x57aab36675b11e24,
  358. 0x835582d896b4d13f,
  359. 0x4808736e213036e,
  360. ]));
  361. assert_eq!(f1 * &f2, f3);
  362. }
  363. #[test]
  364. fn test_fr_bytes() {
  365. let f1_from_repr = Fr::from(BigInteger([
  366. 0xc81265fb4130fe0c,
  367. 0xb308836c14e22279,
  368. 0x699e887f96bff372,
  369. 0x84ecc7e76c11ad,
  370. ]));
  371. let mut f1_bytes = [0u8; 32];
  372. f1_from_repr.write(f1_bytes.as_mut()).unwrap();
  373. let f1 = Fr::read(f1_bytes.as_ref()).unwrap();
  374. assert_eq!(f1_from_repr, f1);
  375. }
  376. #[test]
  377. fn test_fr_from_str() {
  378. let f100_from_repr = Fr::from(BigInteger([0x64, 0, 0, 0]));
  379. let f100 = Fr::from_str("100").unwrap();
  380. assert_eq!(f100_from_repr, f100);
  381. }