2024-10-02 22:55:15 +02:00

103 lines
3.2 KiB
Haskell

{-# LANGUAGE Strict #-}
module Poseidon2.Permutation where
--------------------------------------------------------------------------------
import Data.Array (Array)
import Data.Array.IArray
import Poseidon2.Constants
import Goldilocks
import Common
--------------------------------------------------------------------------------
permutation :: State -> State
permutation
= finalRounds
. internalRounds
. initialRounds
. externalDiffusion
--------------------------------------------------------------------------------
initialRounds :: State -> State
initialRounds
= externalRound (initialRoundConsts ! 3)
. externalRound (initialRoundConsts ! 2)
. externalRound (initialRoundConsts ! 1)
. externalRound (initialRoundConsts ! 0)
internalRounds :: State -> State
internalRounds = foldr1 (.) (map (internalRound $) (reverse internalRoundConsts))
finalRounds :: State -> State
finalRounds
= externalRound (finalRoundConsts ! 3)
. externalRound (finalRoundConsts ! 2)
. externalRound (finalRoundConsts ! 1)
. externalRound (finalRoundConsts ! 0)
--------------------------------------------------------------------------------
externalRound :: [F] -> State -> State
externalRound rcs = externalDiffusion . sboxExternal rcs
internalRound :: F -> State -> State
internalRound rc = internalDiffusion . sboxInternal rc
--------------------------------------------------------------------------------
sbox1 :: F -> F
sbox1 x = pow x 7
sboxRC :: F -> F -> F
sboxRC rc x = sbox1 (x+rc)
sboxInternal :: F -> State -> State
sboxInternal rc s = s // [ (0, sboxRC rc (s!0)) ]
sboxExternal :: [F] -> State -> State
sboxExternal rcs s = listArray (0,11) $ zipWith sboxRC rcs (elems s)
--------------------------------------------------------------------------------
internalDiffusion :: State -> State
internalDiffusion state = listArray (0,11) $ [ s + (state!i * internalDiagElems!i) | i<-[0..11] ] where
s = sum (elems state)
{-
matM4 :: Array (Int,Int) F
matM4 = amap toF $ listArray ((0,0),(3,3))
[ 5 , 7 , 1 , 3
, 4 , 6 , 1 , 1
, 1 , 3 , 5 , 7
, 1 , 1 , 4 , 6
]
-}
matM12:: Array (Int,Int) F
matM12 = amap toF $ listArray ((0,0),(11,11))
[ 2*5 , 2*7 , 2*1 , 2*3 , 5 , 7 , 1 , 3 , 5 , 7 , 1 , 3
, 2*4 , 2*6 , 2*1 , 2*1 , 4 , 6 , 1 , 1 , 4 , 6 , 1 , 1
, 2*1 , 2*3 , 2*5 , 2*7 , 1 , 3 , 5 , 7 , 1 , 3 , 5 , 7
, 2*1 , 2*1 , 2*4 , 2*6 , 1 , 1 , 4 , 6 , 1 , 1 , 4 , 6
, 5 , 7 , 1 , 3 , 2*5 , 2*7 , 2*1 , 2*3 , 5 , 7 , 1 , 3
, 4 , 6 , 1 , 1 , 2*4 , 2*6 , 2*1 , 2*1 , 4 , 6 , 1 , 1
, 1 , 3 , 5 , 7 , 2*1 , 2*3 , 2*5 , 2*7 , 1 , 3 , 5 , 7
, 1 , 1 , 4 , 6 , 2*1 , 2*1 , 2*4 , 2*6 , 1 , 1 , 4 , 6
, 5 , 7 , 1 , 3 , 5 , 7 , 1 , 3 , 2*5 , 2*7 , 2*1 , 2*3
, 4 , 6 , 1 , 1 , 4 , 6 , 1 , 1 , 2*4 , 2*6 , 2*1 , 2*1
, 1 , 3 , 5 , 7 , 1 , 3 , 5 , 7 , 2*1 , 2*3 , 2*5 , 2*7
, 1 , 1 , 4 , 6 , 1 , 1 , 4 , 6 , 2*1 , 2*1 , 2*4 , 2*6
]
externalDiffusion :: State -> State
externalDiffusion state = listArray (0,11)
[ sum [ matM12!(i,j) * state!j | j<-[0..11] ]
| i<-[0..11]
]
--------------------------------------------------------------------------------