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.

261 lines
8.6 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. extern crate rand;
  2. #[macro_use]
  3. extern crate ff;
  4. use ff::*;
  5. #[derive(PrimeField)]
  6. #[PrimeFieldModulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"]
  7. #[PrimeFieldGenerator = "7"]
  8. pub struct Fr(FrRepr);
  9. mod constants;
  10. #[derive(Debug)]
  11. pub struct Constants {
  12. pub c: Vec<Vec<Fr>>,
  13. pub m: Vec<Vec<Vec<Fr>>>,
  14. pub n_rounds_f: usize,
  15. pub n_rounds_p: Vec<usize>,
  16. }
  17. pub fn load_constants() -> Constants {
  18. let (c_str, m_str) = constants::constants();
  19. let mut c: Vec<Vec<Fr>> = Vec::new();
  20. for i in 0..c_str.len() {
  21. let mut cci: Vec<Fr> = Vec::new();
  22. for j in 0..c_str[i].len() {
  23. let b: Fr = Fr::from_str(c_str[i][j]).unwrap();
  24. cci.push(b);
  25. }
  26. c.push(cci);
  27. }
  28. let mut m: Vec<Vec<Vec<Fr>>> = Vec::new();
  29. for i in 0..m_str.len() {
  30. let mut mi: Vec<Vec<Fr>> = Vec::new();
  31. for j in 0..m_str[i].len() {
  32. let mut mij: Vec<Fr> = Vec::new();
  33. for k in 0..m_str[i][j].len() {
  34. let b: Fr = Fr::from_str(m_str[i][j][k]).unwrap();
  35. mij.push(b);
  36. }
  37. mi.push(mij);
  38. }
  39. m.push(mi);
  40. }
  41. Constants {
  42. c: c,
  43. m: m,
  44. n_rounds_f: 8,
  45. n_rounds_p: vec![56, 57, 56, 60, 60, 63, 64, 63],
  46. }
  47. }
  48. pub struct Poseidon {
  49. constants: Constants,
  50. }
  51. impl Poseidon {
  52. pub fn new() -> Poseidon {
  53. Poseidon {
  54. constants: load_constants(),
  55. }
  56. }
  57. pub fn ark(&self, state: &mut Vec<Fr>, c: &Vec<Fr>, it: usize) {
  58. for i in 0..state.len() {
  59. state[i].add_assign(&c[it + i]);
  60. }
  61. }
  62. pub fn sbox(&self, n_rounds_f: usize, n_rounds_p: usize, state: &mut Vec<Fr>, i: usize) {
  63. if i < n_rounds_f / 2 || i >= n_rounds_f / 2 + n_rounds_p {
  64. for j in 0..state.len() {
  65. let aux = state[j];
  66. state[j].square();
  67. state[j].square();
  68. state[j].mul_assign(&aux);
  69. }
  70. } else {
  71. let aux = state[0];
  72. state[0].square();
  73. state[0].square();
  74. state[0].mul_assign(&aux);
  75. }
  76. }
  77. pub fn mix(&self, state: &Vec<Fr>, m: &Vec<Vec<Fr>>) -> Vec<Fr> {
  78. let mut new_state: Vec<Fr> = Vec::new();
  79. for i in 0..state.len() {
  80. new_state.push(Fr::zero());
  81. for j in 0..state.len() {
  82. let mut mij = m[j][i];
  83. mij.mul_assign(&state[j]);
  84. new_state[i].add_assign(&mij);
  85. }
  86. }
  87. new_state.clone()
  88. }
  89. pub fn hash(&self, inp: Vec<Fr>) -> Result<Fr, String> {
  90. let t = inp.len() + 1;
  91. if inp.len() == 0 || inp.len() >= self.constants.n_rounds_p.len() - 1 {
  92. return Err("Wrong inputs length".to_string());
  93. }
  94. let n_rounds_f = self.constants.n_rounds_f.clone();
  95. let n_rounds_p = self.constants.n_rounds_p[t - 2].clone();
  96. let mut state = inp.clone();
  97. for _ in inp.len()..t {
  98. state.push(Fr::zero());
  99. }
  100. // state[state.len() - 1] = Fr::zero();
  101. for i in 0..(n_rounds_f + n_rounds_p) {
  102. self.ark(&mut state, &self.constants.c[t - 2], i * t);
  103. self.sbox(n_rounds_f, n_rounds_p, &mut state, i);
  104. if i < n_rounds_f + n_rounds_p - 1 {
  105. state = self.mix(&state, &self.constants.m[t - 2]);
  106. }
  107. }
  108. Ok(state[0])
  109. }
  110. }
  111. #[cfg(test)]
  112. mod tests {
  113. use super::*;
  114. #[test]
  115. fn test_ff() {
  116. let a = Fr::from_repr(FrRepr::from(2)).unwrap();
  117. assert_eq!(
  118. "0000000000000000000000000000000000000000000000000000000000000002",
  119. to_hex(&a)
  120. );
  121. let b: Fr = Fr::from_str(
  122. "21888242871839275222246405745257275088548364400416034343698204186575808495619",
  123. )
  124. .unwrap();
  125. assert_eq!(
  126. "0000000000000000000000000000000000000000000000000000000000000002",
  127. to_hex(&b)
  128. );
  129. assert_eq!(&a, &b);
  130. }
  131. #[test]
  132. fn test_load_constants() {
  133. let cons = load_constants();
  134. assert_eq!(
  135. cons.c[0][0].to_string(),
  136. "Fr(0x09c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7)"
  137. );
  138. assert_eq!(
  139. cons.c[cons.c.len() - 1][0].to_string(),
  140. "Fr(0x2088ce9534577bf38be7bc457f2756d558d66e0c07b9cc001a580bd42cda0e77)"
  141. );
  142. assert_eq!(
  143. cons.m[0][0][0].to_string(),
  144. "Fr(0x066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5)"
  145. );
  146. assert_eq!(
  147. cons.m[cons.m.len() - 1][0][0].to_string(),
  148. "Fr(0x0190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56)"
  149. );
  150. }
  151. #[test]
  152. fn test_hash() {
  153. let b0: Fr = Fr::from_str("0").unwrap();
  154. let b1: Fr = Fr::from_str("1").unwrap();
  155. let b2: Fr = Fr::from_str("2").unwrap();
  156. let b3: Fr = Fr::from_str("3").unwrap();
  157. let b4: Fr = Fr::from_str("4").unwrap();
  158. let b5: Fr = Fr::from_str("5").unwrap();
  159. let b6: Fr = Fr::from_str("6").unwrap();
  160. let mut big_arr: Vec<Fr> = Vec::new();
  161. big_arr.push(b1.clone());
  162. let poseidon = Poseidon::new();
  163. let h = poseidon.hash(big_arr.clone()).unwrap();
  164. assert_eq!(
  165. h.to_string(),
  166. "Fr(0x186a5454a7c47c73dfc74ac32ea40a57d27eeb4e2bfc6551dd7b66686d3fd1ab)" // "11043376183861534927536506085090418075369306574649619885724436265926427398571"
  167. );
  168. let mut big_arr: Vec<Fr> = Vec::new();
  169. big_arr.push(b1.clone());
  170. big_arr.push(b2.clone());
  171. let poseidon = Poseidon::new();
  172. let h = poseidon.hash(big_arr.clone()).unwrap();
  173. assert_eq!(
  174. h.to_string(),
  175. "Fr(0x25d86fb7c42fd70a7e800e871f22f2f03a282abb18f86c347a1078a92f713f60)" // "17117985411748610629288516079940078114952304104811071254131751175361957805920"
  176. );
  177. let mut big_arr: Vec<Fr> = Vec::new();
  178. big_arr.push(b1.clone());
  179. big_arr.push(b2.clone());
  180. big_arr.push(b0.clone());
  181. big_arr.push(b0.clone());
  182. big_arr.push(b0.clone());
  183. let poseidon = Poseidon::new();
  184. let h = poseidon.hash(big_arr.clone()).unwrap();
  185. assert_eq!(
  186. h.to_string(),
  187. "Fr(0x08ca0a9154fccd6426092b2404e1ceeb80a7849734f1d3fe7952c2075e489566)" // "3975478831357328722254985704342968745327876719981393787143845259590563829094"
  188. );
  189. let mut big_arr: Vec<Fr> = Vec::new();
  190. big_arr.push(b1.clone());
  191. big_arr.push(b2.clone());
  192. big_arr.push(b0.clone());
  193. big_arr.push(b0.clone());
  194. big_arr.push(b0.clone());
  195. big_arr.push(b0.clone());
  196. let poseidon = Poseidon::new();
  197. let h = poseidon.hash(big_arr.clone()).unwrap();
  198. assert_eq!(
  199. h.to_string(),
  200. "Fr(0x2bb6c270db4ca49d129e315cdad9e0e678c1692c420dbf4667fdabc0f158e4ae)" // "19772360636270345724087386688434825760738403416279047262510528378903625000110"
  201. );
  202. let mut big_arr: Vec<Fr> = Vec::new();
  203. big_arr.push(b3.clone());
  204. big_arr.push(b4.clone());
  205. big_arr.push(b0.clone());
  206. big_arr.push(b0.clone());
  207. big_arr.push(b0.clone());
  208. let poseidon = Poseidon::new();
  209. let h = poseidon.hash(big_arr.clone()).unwrap();
  210. assert_eq!(
  211. h.to_string(),
  212. "Fr(0x07087ef123b0fc18a7487a9b3112aec23601e3d2b7ea27a85b35c7ecb595e6f6)" // "3181200837746671699652342497997860344148947482942465819251904554707352676086"
  213. );
  214. let mut big_arr: Vec<Fr> = Vec::new();
  215. big_arr.push(b3.clone());
  216. big_arr.push(b4.clone());
  217. big_arr.push(b0.clone());
  218. big_arr.push(b0.clone());
  219. big_arr.push(b0.clone());
  220. big_arr.push(b0.clone());
  221. let h = poseidon.hash(big_arr.clone()).unwrap();
  222. assert_eq!(
  223. h.to_string(),
  224. "Fr(0x128a815839bb66db834533b9c837e5a09df55e90aa9aba7ad46782234e083c20)" // "8386348873272147968934270337233829407378789978142456170950021426339096575008"
  225. );
  226. let mut big_arr: Vec<Fr> = Vec::new();
  227. big_arr.push(b1.clone());
  228. big_arr.push(b2.clone());
  229. big_arr.push(b3.clone());
  230. big_arr.push(b4.clone());
  231. big_arr.push(b5.clone());
  232. big_arr.push(b6.clone());
  233. let h = poseidon.hash(big_arr.clone()).unwrap();
  234. assert_eq!(
  235. h.to_string(),
  236. "Fr(0x0b807dafd5ecc62acdf7ae48e3a1dfb14ccc1ce398f865ac85ff0b4afd90ea6c)" // "5202465217520500374834597824465244016759843635092906214933648999760272616044"
  237. );
  238. }
  239. }