arnaucube
arnaucube/poseidon-rsPublic Self-hosted repository
poseidon-rs/src/lib.rs
src/lib.rsRaw
  1extern crate rand;
  2#[macro_use]
  3extern crate ff;
  4use ff::*;
  5
  6#[derive(PrimeField)]
  7#[PrimeFieldModulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"]
  8#[PrimeFieldGenerator = "7"]
  9pub struct Fr(FrRepr);
 10
 11const NROUNDSF: usize = 8;
 12const NROUNDSP: usize = 57;
 13const T: usize = 6;
 14
 15#[derive(Debug)]
 16pub struct Constants {
 17    c: Vec<Fr>,
 18    m: Vec<Vec<Fr>>,
 19}
 20
 21pub fn load_constants() -> Constants {
 22    let c_str: Vec<&str> = vec![
 23        "14397397413755236225575615486459253198602422701513067526754101844196324375522",
 24        "10405129301473404666785234951972711717481302463898292859783056520670200613128",
 25        "5179144822360023508491245509308555580251733042407187134628755730783052214509",
 26        "9132640374240188374542843306219594180154739721841249568925550236430986592615",
 27        "20360807315276763881209958738450444293273549928693737723235350358403012458514",
 28        "17933600965499023212689924809448543050840131883187652471064418452962948061619",
 29        "3636213416533737411392076250708419981662897009810345015164671602334517041153",
 30        "2008540005368330234524962342006691994500273283000229509835662097352946198608",
 31        "16018407964853379535338740313053768402596521780991140819786560130595652651567",
 32        "20653139667070586705378398435856186172195806027708437373983929336015162186471",
 33        "17887713874711369695406927657694993484804203950786446055999405564652412116765",
 34        "4852706232225925756777361208698488277369799648067343227630786518486608711772",
 35        "8969172011633935669771678412400911310465619639756845342775631896478908389850",
 36        "20570199545627577691240476121888846460936245025392381957866134167601058684375",
 37        "16442329894745639881165035015179028112772410105963688121820543219662832524136",
 38        "20060625627350485876280451423010593928172611031611836167979515653463693899374",
 39        "16637282689940520290130302519163090147511023430395200895953984829546679599107",
 40        "15599196921909732993082127725908821049411366914683565306060493533569088698214",
 41        "16894591341213863947423904025624185991098788054337051624251730868231322135455",
 42        "1197934381747032348421303489683932612752526046745577259575778515005162320212",
 43        "6172482022646932735745595886795230725225293469762393889050804649558459236626",
 44        "21004037394166516054140386756510609698837211370585899203851827276330669555417",
 45        "15262034989144652068456967541137853724140836132717012646544737680069032573006",
 46        "15017690682054366744270630371095785995296470601172793770224691982518041139766",
 47        "15159744167842240513848638419303545693472533086570469712794583342699782519832",
 48        "11178069035565459212220861899558526502477231302924961773582350246646450941231",
 49        "21154888769130549957415912997229564077486639529994598560737238811887296922114",
 50        "20162517328110570500010831422938033120419484532231241180224283481905744633719",
 51        "2777362604871784250419758188173029886707024739806641263170345377816177052018",
 52        "15732290486829619144634131656503993123618032247178179298922551820261215487562",
 53        "6024433414579583476444635447152826813568595303270846875177844482142230009826",
 54        "17677827682004946431939402157761289497221048154630238117709539216286149983245",
 55        "10716307389353583413755237303156291454109852751296156900963208377067748518748",
 56        "14925386988604173087143546225719076187055229908444910452781922028996524347508",
 57        "8940878636401797005293482068100797531020505636124892198091491586778667442523",
 58        "18911747154199663060505302806894425160044925686870165583944475880789706164410",
 59        "8821532432394939099312235292271438180996556457308429936910969094255825456935",
 60        "20632576502437623790366878538516326728436616723089049415538037018093616927643",
 61        "71447649211767888770311304010816315780740050029903404046389165015534756512",
 62        "2781996465394730190470582631099299305677291329609718650018200531245670229393",
 63        "12441376330954323535872906380510501637773629931719508864016287320488688345525",
 64        "2558302139544901035700544058046419714227464650146159803703499681139469546006",
 65        "10087036781939179132584550273563255199577525914374285705149349445480649057058",
 66        "4267692623754666261749551533667592242661271409704769363166965280715887854739",
 67        "4945579503584457514844595640661884835097077318604083061152997449742124905548",
 68        "17742335354489274412669987990603079185096280484072783973732137326144230832311",
 69        "6266270088302506215402996795500854910256503071464802875821837403486057988208",
 70        "2716062168542520412498610856550519519760063668165561277991771577403400784706",
 71        "19118392018538203167410421493487769944462015419023083813301166096764262134232",
 72        "9386595745626044000666050847309903206827901310677406022353307960932745699524",
 73        "9121640807890366356465620448383131419933298563527245687958865317869840082266",
 74        "3078975275808111706229899605611544294904276390490742680006005661017864583210",
 75        "7157404299437167354719786626667769956233708887934477609633504801472827442743",
 76        "14056248655941725362944552761799461694550787028230120190862133165195793034373",
 77        "14124396743304355958915937804966111851843703158171757752158388556919187839849",
 78        "11851254356749068692552943732920045260402277343008629727465773766468466181076",
 79        "9799099446406796696742256539758943483211846559715874347178722060519817626047",
 80        "10156146186214948683880719664738535455146137901666656566575307300522957959544",
 81        "19908645952733301583346063785055921934459499091029406575311417879963332475861",
 82        "11766105336238068471342414351862472329437473380853789942065610694000443387471",
 83        "11002137593249972174092192767251572171769044073555430468487809799220351297047",
 84        "284136377911685911941431040940403846843630064858778505937392780738953624163",
 85        "19448733709802908339787967270452055364068697565906862913410983275341804035680",
 86        "14423660424692802524250720264041003098290275890428483723270346403986712981505",
 87        "10635360132728137321700090133109897687122647659471659996419791842933639708516",
 88    ];
 89
 90    let m_str: Vec<Vec<&str>> = vec![
 91        vec![
 92            "19167410339349846567561662441069598364702008768579734801591448511131028229281",
 93            "14183033936038168803360723133013092560869148726790180682363054735190196956789",
 94            "9067734253445064890734144122526450279189023719890032859456830213166173619761",
 95            "16378664841697311562845443097199265623838619398287411428110917414833007677155",
 96            "12968540216479938138647596899147650021419273189336843725176422194136033835172",
 97            "3636162562566338420490575570584278737093584021456168183289112789616069756675",
 98        ],
 99        vec![
100            "17034139127218860091985397764514160131253018178110701196935786874261236172431",
101            "2799255644797227968811798608332314218966179365168250111693473252876996230317",
102            "2482058150180648511543788012634934806465808146786082148795902594096349483974",
103            "16563522740626180338295201738437974404892092704059676533096069531044355099628",
104            "10468644849657689537028565510142839489302836569811003546969773105463051947124",
105            "3328913364598498171733622353010907641674136720305714432354138807013088636408",
106        ],
107        vec![
108            "18985203040268814769637347880759846911264240088034262814847924884273017355969",
109            "8652975463545710606098548415650457376967119951977109072274595329619335974180",
110            "970943815872417895015626519859542525373809485973005165410533315057253476903",
111            "19406667490568134101658669326517700199745817783746545889094238643063688871948",
112            "17049854690034965250221386317058877242629221002521630573756355118745574274967",
113            "4964394613021008685803675656098849539153699842663541444414978877928878266244",
114        ],
115        vec![
116            "19025623051770008118343718096455821045904242602531062247152770448380880817517",
117            "9077319817220936628089890431129759976815127354480867310384708941479362824016",
118            "4770370314098695913091200576539533727214143013236894216582648993741910829490",
119            "4298564056297802123194408918029088169104276109138370115401819933600955259473",
120            "6905514380186323693285869145872115273350947784558995755916362330070690839131",
121            "4783343257810358393326889022942241108539824540285247795235499223017138301952",
122        ],
123        vec![
124            "16205238342129310687768799056463408647672389183328001070715567975181364448609",
125            "8303849270045876854140023508764676765932043944545416856530551331270859502246",
126            "20218246699596954048529384569730026273241102596326201163062133863539137060414",
127            "1712845821388089905746651754894206522004527237615042226559791118162382909269",
128            "13001155522144542028910638547179410124467185319212645031214919884423841839406",
129            "16037892369576300958623292723740289861626299352695838577330319504984091062115",
130        ],
131        vec![
132            "15162889384227198851506890526431746552868519326873025085114621698588781611738",
133            "13272957914179340594010910867091459756043436017766464331915862093201960540910",
134            "9416416589114508529880440146952102328470363729880726115521103179442988482948",
135            "8035240799672199706102747147502951589635001418759394863664434079699838251138",
136            "21642389080762222565487157652540372010968704000567605990102641816691459811717",
137            "20261355950827657195644012399234591122288573679402601053407151083849785332516",
138        ],
139    ];
140
141    let mut c: Vec<Fr> = Vec::new();
142    for i in 0..c_str.len() {
143        let n: Fr = Fr::from_str(c_str[i]).unwrap();
144        c.push(n);
145    }
146    let mut m: Vec<Vec<Fr>> = Vec::new();
147    for i in 0..m_str.len() {
148        let mut mj: Vec<Fr> = Vec::new();
149        for j in 0..m_str[i].len() {
150            let n: Fr = Fr::from_str(m_str[i][j]).unwrap();
151            mj.push(n);
152        }
153        m.push(mj);
154    }
155    Constants { c: c, m: m }
156}
157
158pub struct Poseidon {
159    constants: Constants,
160}
161impl Poseidon {
162    pub fn new() -> Poseidon {
163        Poseidon {
164            constants: load_constants(),
165        }
166    }
167    pub fn ark(&self, state: &Vec<Fr>, c: &Fr) -> Vec<Fr> {
168        let mut new_state: Vec<Fr> = state.clone();
169        for i in 0..state.len() {
170            new_state[i] = state[i];
171            new_state[i].add_assign(c);
172        }
173
174        new_state
175    }
176
177    pub fn sbox(&self, state: &Vec<Fr>, i: usize) -> Vec<Fr> {
178        let mut new_state: Vec<Fr> = state.clone();
179        if i < NROUNDSF / 2 || i >= NROUNDSF / 2 + NROUNDSP {
180            for j in 0..T {
181                new_state[j] = state[j];
182                new_state[j].square();
183                new_state[j].square();
184                new_state[j].mul_assign(&state[j]);
185            }
186        } else {
187            new_state[0] = state[0];
188            new_state[0].square();
189            new_state[0].square();
190            new_state[0].mul_assign(&state[0]);
191        }
192        new_state
193    }
194
195    pub fn mix(&self, state: &Vec<Fr>, m: &Vec<Vec<Fr>>) -> Vec<Fr> {
196        let mut new_state: Vec<Fr> = Vec::new();
197        for i in 0..state.len() {
198            new_state.push(Fr::zero());
199            for j in 0..state.len() {
200                let mut mij = m[i][j];
201                mij.mul_assign(&state[j]);
202                new_state[i].add_assign(&mij);
203            }
204        }
205        new_state.clone()
206    }
207
208    pub fn hash(&self, inp: Vec<Fr>) -> Result<Fr, String> {
209        if inp.len() == 0 || inp.len() > T {
210            return Err("Wrong inputs length".to_string());
211        }
212
213        let mut state = inp.clone();
214        for _ in inp.len()..T {
215            state.push(Fr::zero());
216        }
217
218        for i in 0..(NROUNDSF + NROUNDSP) {
219            state = self.ark(&state, &self.constants.c[i]);
220            state = self.sbox(&state, i);
221            state = self.mix(&state, &self.constants.m);
222        }
223
224        Ok(state[0])
225    }
226}
227
228#[cfg(test)]
229mod tests {
230    use super::*;
231
232    #[test]
233    fn test_ff() {
234        let a = Fr::from_repr(FrRepr::from(2)).unwrap();
235        assert_eq!(
236            "0000000000000000000000000000000000000000000000000000000000000002",
237            to_hex(&a)
238        );
239        println!("`2` into hex = {}", to_hex(&a));
240    }
241
242    #[test]
243    fn test_load_constants() {
244        let constants = load_constants();
245        println!("{:?}", constants.c[0].to_string());
246        assert_eq!(
247            constants.c[0].to_string(),
248            "Fr(0x1fd4a35e68f0946f8f5dfd2ac9d7882ce2466ec1c9766f69b5a14c3f84a17be2)"
249        );
250        assert_eq!(
251            constants.c[constants.c.len() - 1].to_string(),
252            "Fr(0x1783668830df79d79707da6a0e7c023c5f54a112be7ee3f7d49b420213ab7f64)"
253        );
254        assert_eq!(
255            constants.m[0][0].to_string(),
256            "Fr(0x2a605eab3c12c29701b9a8944a16ff3d64c199efa7c857c65e4c0560ab3b0ca1)"
257        );
258        assert_eq!(
259            constants.m[constants.m.len() - 1][0].to_string(),
260            "Fr(0x2185e429a96435c62e21e7091f4262685769e43fa49c9d40f88c41016c588ada)"
261        );
262    }
263
264    #[test]
265    fn test_hash() {
266        let b1: Fr = Fr::from_str("1").unwrap();
267        let b2: Fr = Fr::from_str("2").unwrap();
268        let mut big_arr: Vec<Fr> = Vec::new();
269        big_arr.push(b1.clone());
270        big_arr.push(b2.clone());
271        let poseidon = Poseidon::new();
272        let h = poseidon.hash(big_arr.clone()).unwrap();
273        assert_eq!(
274            h.to_string(),
275            "Fr(0x1b10d227ef9aa736dc05bba919a8462ce45bc5b7d632e8ff9bfe6874a002eaed)" // "12242166908188651009877250812424843524687801523336557272219921456462821518061"
276        );
277
278        let b3: Fr = Fr::from_str("3").unwrap();
279        let b4: Fr = Fr::from_str("4").unwrap();
280        let mut big_arr34: Vec<Fr> = Vec::new();
281        big_arr34.push(b3.clone());
282        big_arr34.push(b4.clone());
283        let h34 = poseidon.hash(big_arr34.clone()).unwrap();
284        assert_eq!(
285            h34.to_string(),
286            "Fr(0x25fe79e16e9d530a400584ffe556b1fe69acda374065860c43698cab1c16b3a1)" // "17185195740979599334254027721507328033796809509313949281114643312710535000993"
287        );
288    }
289}