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.

256 lines
8.4 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
  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[i][j];
  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 = vec![Fr::zero(); t];
  97. state[1..].clone_from_slice(&inp);
  98. for i in 0..(n_rounds_f + n_rounds_p) {
  99. self.ark(&mut state, &self.constants.c[t - 2], i * t);
  100. self.sbox(n_rounds_f, n_rounds_p, &mut state, i);
  101. state = self.mix(&state, &self.constants.m[t - 2]);
  102. }
  103. Ok(state[0])
  104. }
  105. }
  106. #[cfg(test)]
  107. mod tests {
  108. use super::*;
  109. #[test]
  110. fn test_ff() {
  111. let a = Fr::from_repr(FrRepr::from(2)).unwrap();
  112. assert_eq!(
  113. "0000000000000000000000000000000000000000000000000000000000000002",
  114. to_hex(&a)
  115. );
  116. let b: Fr = Fr::from_str(
  117. "21888242871839275222246405745257275088548364400416034343698204186575808495619",
  118. )
  119. .unwrap();
  120. assert_eq!(
  121. "0000000000000000000000000000000000000000000000000000000000000002",
  122. to_hex(&b)
  123. );
  124. assert_eq!(&a, &b);
  125. }
  126. #[test]
  127. fn test_load_constants() {
  128. let cons = load_constants();
  129. assert_eq!(
  130. cons.c[0][0].to_string(),
  131. "Fr(0x09c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7)"
  132. );
  133. assert_eq!(
  134. cons.c[cons.c.len() - 1][0].to_string(),
  135. "Fr(0x2088ce9534577bf38be7bc457f2756d558d66e0c07b9cc001a580bd42cda0e77)"
  136. );
  137. assert_eq!(
  138. cons.m[0][0][0].to_string(),
  139. "Fr(0x066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5)"
  140. );
  141. assert_eq!(
  142. cons.m[cons.m.len() - 1][0][0].to_string(),
  143. "Fr(0x0190f922d97c8a7dcf0a142a3be27749d1c64bc22f1c556aaa24925d158cac56)"
  144. );
  145. }
  146. #[test]
  147. fn test_hash() {
  148. let b0: Fr = Fr::from_str("0").unwrap();
  149. let b1: Fr = Fr::from_str("1").unwrap();
  150. let b2: Fr = Fr::from_str("2").unwrap();
  151. let b3: Fr = Fr::from_str("3").unwrap();
  152. let b4: Fr = Fr::from_str("4").unwrap();
  153. let b5: Fr = Fr::from_str("5").unwrap();
  154. let b6: Fr = Fr::from_str("6").unwrap();
  155. let mut big_arr: Vec<Fr> = Vec::new();
  156. big_arr.push(b1.clone());
  157. let poseidon = Poseidon::new();
  158. let h = poseidon.hash(big_arr.clone()).unwrap();
  159. assert_eq!(
  160. h.to_string(),
  161. "Fr(0x29176100eaa962bdc1fe6c654d6a3c130e96a4d1168b33848b897dc502820133)" // "18586133768512220936620570745912940619677854269274689475585506675881198879027"
  162. );
  163. let mut big_arr: Vec<Fr> = Vec::new();
  164. big_arr.push(b1.clone());
  165. big_arr.push(b2.clone());
  166. let poseidon = Poseidon::new();
  167. let h = poseidon.hash(big_arr.clone()).unwrap();
  168. assert_eq!(
  169. h.to_string(),
  170. "Fr(0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a)" // "7853200120776062878684798364095072458815029376092732009249414926327459813530"
  171. );
  172. let mut big_arr: Vec<Fr> = Vec::new();
  173. big_arr.push(b1.clone());
  174. big_arr.push(b2.clone());
  175. big_arr.push(b0.clone());
  176. big_arr.push(b0.clone());
  177. big_arr.push(b0.clone());
  178. let poseidon = Poseidon::new();
  179. let h = poseidon.hash(big_arr.clone()).unwrap();
  180. assert_eq!(
  181. h.to_string(),
  182. "Fr(0x024058dd1e168f34bac462b6fffe58fd69982807e9884c1c6148182319cee427)" // "1018317224307729531995786483840663576608797660851238720571059489595066344487"
  183. );
  184. let mut big_arr: Vec<Fr> = Vec::new();
  185. big_arr.push(b1.clone());
  186. big_arr.push(b2.clone());
  187. big_arr.push(b0.clone());
  188. big_arr.push(b0.clone());
  189. big_arr.push(b0.clone());
  190. big_arr.push(b0.clone());
  191. let poseidon = Poseidon::new();
  192. let h = poseidon.hash(big_arr.clone()).unwrap();
  193. assert_eq!(
  194. h.to_string(),
  195. "Fr(0x21e82f465e00a15965e97a44fe3c30f3bf5279d8bf37d4e65765b6c2550f42a1)" // "15336558801450556532856248569924170992202208561737609669134139141992924267169"
  196. );
  197. let mut big_arr: Vec<Fr> = Vec::new();
  198. big_arr.push(b3.clone());
  199. big_arr.push(b4.clone());
  200. big_arr.push(b0.clone());
  201. big_arr.push(b0.clone());
  202. big_arr.push(b0.clone());
  203. let poseidon = Poseidon::new();
  204. let h = poseidon.hash(big_arr.clone()).unwrap();
  205. assert_eq!(
  206. h.to_string(),
  207. "Fr(0x0cd93f1bab9e8c9166ef00f2a1b0e1d66d6a4145e596abe0526247747cc71214)" // "5811595552068139067952687508729883632420015185677766880877743348592482390548"
  208. );
  209. let mut big_arr: Vec<Fr> = Vec::new();
  210. big_arr.push(b3.clone());
  211. big_arr.push(b4.clone());
  212. big_arr.push(b0.clone());
  213. big_arr.push(b0.clone());
  214. big_arr.push(b0.clone());
  215. big_arr.push(b0.clone());
  216. let h = poseidon.hash(big_arr.clone()).unwrap();
  217. assert_eq!(
  218. h.to_string(),
  219. "Fr(0x1b1caddfc5ea47e09bb445a7447eb9694b8d1b75a97fff58e884398c6b22825a)" // "12263118664590987767234828103155242843640892839966517009184493198782366909018"
  220. );
  221. let mut big_arr: Vec<Fr> = Vec::new();
  222. big_arr.push(b1.clone());
  223. big_arr.push(b2.clone());
  224. big_arr.push(b3.clone());
  225. big_arr.push(b4.clone());
  226. big_arr.push(b5.clone());
  227. big_arr.push(b6.clone());
  228. let h = poseidon.hash(big_arr.clone()).unwrap();
  229. assert_eq!(
  230. h.to_string(),
  231. "Fr(0x2d1a03850084442813c8ebf094dea47538490a68b05f2239134a4cca2f6302e1)" // "20400040500897583745843009878988256314335038853985262692600694741116813247201"
  232. );
  233. }
  234. }