2023-10-25 18:12:26 +02:00

48 lines
1.3 KiB
Haskell

-- | The Poseidon2 permutation
module Poseidon2.Permutation where
--------------------------------------------------------------------------------
import ZK.Algebra.Curves.BN128.Fr.Mont (Fr)
import Poseidon2.RoundConsts
--------------------------------------------------------------------------------
sbox :: Fr -> Fr
sbox x = x4*x where
x2 = x *x
x4 = x2*x2
internalRound :: Fr -> (Fr,Fr,Fr) -> (Fr,Fr,Fr)
internalRound c (x,y,z) =
( 2*x' + y + z
, x' + 2*y + z
, x' + y + 3*z
)
where
x' = sbox (x + c)
externalRound :: (Fr,Fr,Fr) -> (Fr,Fr,Fr) -> (Fr,Fr,Fr)
externalRound (cx,cy,cz) (x,y,z) = (x'+s , y'+s , z'+s) where
x' = sbox (x + cx)
y' = sbox (y + cy)
z' = sbox (z + cz)
s = x' + y' + z'
linearLayer :: (Fr,Fr,Fr) -> (Fr,Fr,Fr)
linearLayer (x,y,z) = (x+s, y+s, z+s) where s = x+y+z
--------------------------------------------------------------------------------
permutation :: (Fr,Fr,Fr) -> (Fr,Fr,Fr)
permutation
= (\state -> foldl (flip externalRound) state finalRoundConsts )
. (\state -> foldl (flip internalRound) state internalRoundConsts)
. (\state -> foldl (flip externalRound) state initialRoundConsts )
. linearLayer
--------------------------------------------------------------------------------