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.

283 lines
9.9 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
  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,
  43. m,
  44. n_rounds_f: 8,
  45. n_rounds_p: vec![
  46. 56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68,
  47. ],
  48. }
  49. }
  50. pub struct Poseidon {
  51. constants: Constants,
  52. }
  53. impl Poseidon {
  54. pub fn new() -> Poseidon {
  55. Poseidon {
  56. constants: load_constants(),
  57. }
  58. }
  59. pub fn ark(&self, state: &mut Vec<Fr>, c: &Vec<Fr>, it: usize) {
  60. for i in 0..state.len() {
  61. state[i].add_assign(&c[it + i]);
  62. }
  63. }
  64. pub fn sbox(&self, n_rounds_f: usize, n_rounds_p: usize, state: &mut Vec<Fr>, i: usize) {
  65. if i < n_rounds_f / 2 || i >= n_rounds_f / 2 + n_rounds_p {
  66. for j in 0..state.len() {
  67. let aux = state[j];
  68. state[j].square();
  69. state[j].square();
  70. state[j].mul_assign(&aux);
  71. }
  72. } else {
  73. let aux = state[0];
  74. state[0].square();
  75. state[0].square();
  76. state[0].mul_assign(&aux);
  77. }
  78. }
  79. pub fn mix(&self, state: &Vec<Fr>, m: &Vec<Vec<Fr>>) -> Vec<Fr> {
  80. let mut new_state: Vec<Fr> = Vec::new();
  81. for i in 0..state.len() {
  82. new_state.push(Fr::zero());
  83. for j in 0..state.len() {
  84. let mut mij = m[i][j];
  85. mij.mul_assign(&state[j]);
  86. new_state[i].add_assign(&mij);
  87. }
  88. }
  89. new_state.clone()
  90. }
  91. pub fn hash(&self, inp: Vec<Fr>) -> Result<Fr, String> {
  92. let t = inp.len() + 1;
  93. // if inp.len() == 0 || inp.len() >= self.constants.n_rounds_p.len() - 1 {
  94. if inp.is_empty() || inp.len() > self.constants.n_rounds_p.len() {
  95. return Err("Wrong inputs length".to_string());
  96. }
  97. let n_rounds_f = self.constants.n_rounds_f.clone();
  98. let n_rounds_p = self.constants.n_rounds_p[t - 2].clone();
  99. let mut state = vec![Fr::zero(); t];
  100. state[1..].clone_from_slice(&inp);
  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. state = self.mix(&state, &self.constants.m[t - 2]);
  105. }
  106. Ok(state[0])
  107. }
  108. }
  109. #[cfg(test)]
  110. mod tests {
  111. use super::*;
  112. #[test]
  113. fn test_ff() {
  114. let a = Fr::from_repr(FrRepr::from(2)).unwrap();
  115. assert_eq!(
  116. "0000000000000000000000000000000000000000000000000000000000000002",
  117. to_hex(&a)
  118. );
  119. let b: Fr = Fr::from_str(
  120. "21888242871839275222246405745257275088548364400416034343698204186575808495619",
  121. )
  122. .unwrap();
  123. assert_eq!(
  124. "0000000000000000000000000000000000000000000000000000000000000002",
  125. to_hex(&b)
  126. );
  127. assert_eq!(&a, &b);
  128. }
  129. // #[test]
  130. // fn test_load_constants() {
  131. // let cons = load_constants();
  132. // assert_eq!(
  133. // cons.c[0][0].to_string(),
  134. // "Fr(0x09c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7)"
  135. // );
  136. // assert_eq!(
  137. // cons.c[cons.c.len() - 1][0].to_string(),
  138. // "Fr(0x2088ce9534577bf38be7bc457f2756d558d66e0c07b9cc001a580bd42cda0e77)"
  139. // );
  140. // assert_eq!(
  141. // cons.m[0][0][0].to_string(),
  142. // "Fr(0x066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5)"
  143. // );
  144. // assert_eq!(
  145. // cons.m[cons.m.len() - 1][0][0].to_string(),
  146. // "Fr(0x0190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56)"
  147. // );
  148. // }
  149. #[test]
  150. fn test_hash() {
  151. let b0: Fr = Fr::from_str("0").unwrap();
  152. let b1: Fr = Fr::from_str("1").unwrap();
  153. let b2: Fr = Fr::from_str("2").unwrap();
  154. let b3: Fr = Fr::from_str("3").unwrap();
  155. let b4: Fr = Fr::from_str("4").unwrap();
  156. let b5: Fr = Fr::from_str("5").unwrap();
  157. let b6: Fr = Fr::from_str("6").unwrap();
  158. let b7: Fr = Fr::from_str("7").unwrap();
  159. let b8: Fr = Fr::from_str("8").unwrap();
  160. let b9: Fr = Fr::from_str("9").unwrap();
  161. let b10: Fr = Fr::from_str("10").unwrap();
  162. let b11: Fr = Fr::from_str("11").unwrap();
  163. let b12: Fr = Fr::from_str("12").unwrap();
  164. let b13: Fr = Fr::from_str("13").unwrap();
  165. let b14: Fr = Fr::from_str("14").unwrap();
  166. let b15: Fr = Fr::from_str("15").unwrap();
  167. let b16: Fr = Fr::from_str("16").unwrap();
  168. let poseidon = Poseidon::new();
  169. let big_arr: Vec<Fr> = vec![b1];
  170. // let mut big_arr: Vec<Fr> = Vec::new();
  171. // big_arr.push(b1.clone());
  172. let h = poseidon.hash(big_arr).unwrap();
  173. assert_eq!(
  174. h.to_string(),
  175. "Fr(0x29176100eaa962bdc1fe6c654d6a3c130e96a4d1168b33848b897dc502820133)" // "18586133768512220936620570745912940619677854269274689475585506675881198879027"
  176. );
  177. let big_arr: Vec<Fr> = vec![b1, b2];
  178. let h = poseidon.hash(big_arr).unwrap();
  179. assert_eq!(
  180. h.to_string(),
  181. "Fr(0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a)" // "7853200120776062878684798364095072458815029376092732009249414926327459813530"
  182. );
  183. let big_arr: Vec<Fr> = vec![b1, b2, b0, b0, b0];
  184. let h = poseidon.hash(big_arr).unwrap();
  185. assert_eq!(
  186. h.to_string(),
  187. "Fr(0x024058dd1e168f34bac462b6fffe58fd69982807e9884c1c6148182319cee427)" // "1018317224307729531995786483840663576608797660851238720571059489595066344487"
  188. );
  189. let big_arr: Vec<Fr> = vec![b1, b2, b0, b0, b0, b0];
  190. let h = poseidon.hash(big_arr).unwrap();
  191. assert_eq!(
  192. h.to_string(),
  193. "Fr(0x21e82f465e00a15965e97a44fe3c30f3bf5279d8bf37d4e65765b6c2550f42a1)" // "15336558801450556532856248569924170992202208561737609669134139141992924267169"
  194. );
  195. let big_arr: Vec<Fr> = vec![b3, b4, b0, b0, b0];
  196. let h = poseidon.hash(big_arr).unwrap();
  197. assert_eq!(
  198. h.to_string(),
  199. "Fr(0x0cd93f1bab9e8c9166ef00f2a1b0e1d66d6a4145e596abe0526247747cc71214)" // "5811595552068139067952687508729883632420015185677766880877743348592482390548"
  200. );
  201. let big_arr: Vec<Fr> = vec![b3, b4, b0, b0, b0, b0];
  202. let h = poseidon.hash(big_arr).unwrap();
  203. assert_eq!(
  204. h.to_string(),
  205. "Fr(0x1b1caddfc5ea47e09bb445a7447eb9694b8d1b75a97fff58e884398c6b22825a)" // "12263118664590987767234828103155242843640892839966517009184493198782366909018"
  206. );
  207. let big_arr: Vec<Fr> = vec![b1, b2, b3, b4, b5, b6];
  208. let h = poseidon.hash(big_arr).unwrap();
  209. assert_eq!(
  210. h.to_string(),
  211. "Fr(0x2d1a03850084442813c8ebf094dea47538490a68b05f2239134a4cca2f6302e1)" // "20400040500897583745843009878988256314335038853985262692600694741116813247201"
  212. );
  213. let big_arr: Vec<Fr> = vec![b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14];
  214. let h = poseidon.hash(big_arr).unwrap();
  215. assert_eq!(
  216. h.to_string(),
  217. "Fr(0x1278779aaafc5ca58bf573151005830cdb4683fb26591c85a7464d4f0e527776)", // "8354478399926161176778659061636406690034081872658507739535256090879947077494"
  218. );
  219. let big_arr: Vec<Fr> = vec![b1, b2, b3, b4, b5, b6, b7, b8, b9, b0, b0, b0, b0, b0];
  220. let h = poseidon.hash(big_arr).unwrap();
  221. assert_eq!(
  222. h.to_string(),
  223. "Fr(0x0c3fbfb4d3f583df4124b4b3ac94ca3a0a1948a89fef727204d89de1c4d35693)", // "5540388656744764564518487011617040650780060800286365721923524861648744699539"
  224. );
  225. let big_arr: Vec<Fr> = vec![
  226. b1, b2, b3, b4, b5, b6, b7, b8, b9, b0, b0, b0, b0, b0, b0, b0,
  227. ];
  228. let h = poseidon.hash(big_arr).unwrap();
  229. assert_eq!(
  230. h.to_string(),
  231. "Fr(0x1a456f8563b98c9649877f38b7e36534b241c29d457d307c481cbd12b69bb721)", // "11882816200654282475720830292386643970958445617880627439994635298904836126497"
  232. );
  233. let big_arr: Vec<Fr> = vec![
  234. b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16,
  235. ];
  236. let h = poseidon.hash(big_arr).unwrap();
  237. assert_eq!(
  238. h.to_string(),
  239. "Fr(0x16159a551cbb66108281a48099fff949ae08afd7f1f2ec06de2ffb96b919b765)", // "9989051620750914585850546081941653841776809718687451684622678807385399211877"
  240. );
  241. }
  242. #[test]
  243. fn test_wrong_inputs() {
  244. let b0: Fr = Fr::from_str("0").unwrap();
  245. let b1: Fr = Fr::from_str("1").unwrap();
  246. let b2: Fr = Fr::from_str("2").unwrap();
  247. let poseidon = Poseidon::new();
  248. let big_arr: Vec<Fr> = vec![
  249. b1, b2, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0,
  250. ];
  251. poseidon.hash(big_arr).expect_err("Wrong inputs length");
  252. }
  253. }