Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';Haskell AES密钥扩展有什么问题?_Haskell_Aes_Rijndael - Fatal编程技术网

什么';Haskell AES密钥扩展有什么问题?

什么';Haskell AES密钥扩展有什么问题?,haskell,aes,rijndael,Haskell,Aes,Rijndael,按照中描述密钥扩展的步骤,我编写了此密钥扩展代码。这是整个文件(它也计算S-Box),所以人们可以编译并尝试它 {-# LANGUAGE NoMonomorphismRestriction #-} import Control.Applicative (liftA2) import Data.Bits (xor, shiftL, shiftR, (.|.), (.&.)) import Data.List (transpose, sortBy) import Data.Ord (com

按照中描述密钥扩展的步骤,我编写了此密钥扩展代码。这是整个文件(它也计算S-Box),所以人们可以编译并尝试它

{-# LANGUAGE NoMonomorphismRestriction #-}

import Control.Applicative (liftA2)
import Data.Bits (xor, shiftL, shiftR, (.|.), (.&.))
import Data.List (transpose, sortBy)
import Data.Ord (comparing)
import Data.Word (Word8)
import Numeric (showHex)

keys = f 16 $ f 8 $ f 4 $ f 2 $ f 1 key
 where
  f w n = xpndC . xpndB . xpndA $ xpndD w n

xpndC   :: [[Word8]] -> [[Word8]]
xpndC ws = transpose [head ws, b, zipWith xor b c, last ws]
 where
  (b,c) = (ws !! 1, ws !! 2)

xpndB   :: [[Word8]] -> [[Word8]]
xpndB ws = a : zipWith xor a b : drop 2 ws
 where
  (a,b) = (head ws, ws !! 1)

xpndA   :: [[Word8]] -> [[Word8]]
xpndA ws = zipWith xor a d : tail ws
 where
  (a,d) = (head ws, last ws)

xpndD rc ws = take 3 tW ++ [w']
 where
  w' = zipWith xor (map sub w) [rc, 0, 0, 0]
  tW = transpose ws
  w  = take 4 $ tail $ cycle $ last tW

--------------------------------------------------------------
sub w = get sbox (fromIntegral lo) $ fromIntegral hi
 where
  (hi, lo) = nibs w

get wss x y = (wss !! y) !! x

print' = print . w128 . concat . transpose
 where
  w128 = concatMap (f . (`showHex` ""))
  f w  = (length w < 2) ? (' ':'0':w, ' ':w)

grid _ [] = []
grid n xs = take n xs : grid n (drop n xs)

nibs w    = (shiftR (w .&. 0xF0) 4, w .&. 0x0F)
(⊕)       = xor
p ? (a,b) = if p then a else b; infix 2 ?

---------------------------------------------------
sbox :: [[Word8]]
sbox = grid 16 $ map snd $ sortBy (comparing fst) $ sbx 1 1 []

sbx :: Word8 -> Word8 -> [(Word8, Word8)] -> [(Word8, Word8)]
sbx p q ws
  | length ws == 255 = (0, 0x63) : ws
  | otherwise = sbx p' r $ (p', xf ⊕ 0x63) : ws
 where
  p' = p  ⊕  shiftL p  1 ⊕  ((p .&. 0x80 /= 0) ? (0x1B, 0))
  q1 = foldl (liftA2 (.) xor shiftL) q [1, 2, 4]
  r  = q1 ⊕  ((q1 .&. 0x80 /= 0) ? (0x09, 0))
  xf = r  ⊕  rotl8 r 1 ⊕  rotl8 r 2 ⊕  rotl8 r 3 ⊕  rotl8 r 4

rotl8 w n = (w `shiftL` n) .|. (w `shiftR` (8 - n))

key = [[0,0,0,0],
       [0,0,0,0],
       [0,0,0,0],
       [0,0,0,0]] :: [[Word8]]
{-#语言诺模同构限制#-}
导入控制。应用程序(liftA2)
导入数据位(异或、移位、移位、移位、(.|.)、(.&.))
导入数据列表(转置,排序)
导入数据。Ord(比较)
导入数据。Word(Word8)
导入数字(showHex)
钥匙=f 16$f 8$f 4$f 2$f 1钥匙
哪里
f w n=xpndC。xpndB。xpndA$xpndD w n
xpndC::[[Word8]]->[[Word8]]
xpndC ws=transpose[头ws,b,zipWith xor b c,last ws]
哪里
(b,c)=(ws!!1,ws!!2)
xpndB::[[Word8]]->[[Word8]]
xpndB ws=a:zipWith xor a b:drop 2 ws
哪里
(a,b)=(头部ws,ws!!1)
xpndA::[[Word8]]->[[Word8]]
xpndA ws=zipWith xor a d:tail ws
哪里
(a,d)=(头部ws,最后ws)
xpndD rc ws=take 3 tW++[w']
哪里
w'=zipWith xor(映射子w)[rc,0,0,0]
tW=转置ws
w=取4$tail$循环$last tW
--------------------------------------------------------------
sub w=获取sbox(从积分lo)$从积分hi
哪里
(hi,lo)=笔尖w
获取wss x y=(wss!!y)!!x
打印'=打印。w128。康卡特。转置
哪里
w128=concatMap(f.('showHex`'))
f w=(长度w<2)?('':'0':w'':w)
网格[]=[]
网格nxs=take nxs:grid n(drop nxs)
笔尖w=(移位器(w.和.0xF0)4,w.和.0x0F)
(⊕)       = 异或
p?(a,b)=如果是p,那么a是b;中缀2?
---------------------------------------------------
sbox::[[Word8]]
sbox=网格16$map snd$sortBy(比较fst)$sbx 1[]
sbx::Word8->Word8->[(Word8,Word8)]->[(Word8,Word8)]
sbx p q ws
|长度ws==255=(0,0x63):ws
|否则=sbx p'r$(p',xf⊕ 0x63):ws
哪里
p'=p⊕  移位p 1⊕  ((p.和0x80/=0)?(0x1B,0))
q1=foldl(liftA2(.)xor shiftL)q[1,2,4]
r=q1⊕  ((q1.&0x80/=0)?(0x09,0))
xf=r⊕  rotl8 r 1⊕  rotl8 r 2⊕  rotl8 r 3⊕  rotl8 R4
rotl8 w n=(w`shiftL`n)。|(w`shiftR`(8-n))
键=[[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0]]:[[Word8]]
当我使用全零测试键测试此代码时,它与第四次迭代之前发布的期望值相匹配:
ee 06 da 7b 87 6a 15 81 75 9e 42 b2 7e 91 ee 2b

但当我尝试下一次迭代时:
keys=F16$F8$F4$F2$F1
, 结果的最后32位错误:
7f 2e 2b 88 f8 44 3e 09 8d da 7c bb 91 28 f1 f3

当我使用所有0xFF作为初始密钥时,同样的行为(最后32位错误)也会发生。在随后的迭代中,所有的位都是错误的

如果我使用测试向量
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
,事情会更快出错-我在第二次迭代中开始得到错误的位

这里发生了什么?我注意到Moser先生在第2b部分:4中使用上一轮键的第一列写入了xor,但是没有上一轮的初始键,所以这让我很困惑。这是我做错了吗

作为参考,

您缺少一个步骤

xpndC ws = transpose [head ws, b, zipWith xor b c, last ws]
第四列应该是前一个第四列(您在第一个过程中丢弃了它)和新的第三列的异或

只有在第五次迭代时才可以注意到,
xor x=0
在某种程度上导致了这个错误


次要文体评论

固定结构上的模式匹配没有
(!!)
那么麻烦

还要注意的是,步骤
2b4
3
实际上是一个扫描。大致上,它最终看起来是这样的(名称
schedule\u core
借用了上一个链接):


编辑:修复 解决方案基本上是不丢弃最后一列。作为一个快速修复,您可以通过以下方式在另一个过程中注入它:

keys = f 16 $ f 8 $ f 4 $ f 2 $ f 1 key
 where
  f w n = xpndE (transpose n) . xpndC . xpndB . xpndA $ xpndD w n

xpndE n [a,b,c,_] = transpose [a,b,c,zipWith xor c (last n)]

xpndC = (...) {- remove transpose here -}
一旦你意识到列表很小,
xpnd*
函数的粒度可能有点太细了。如果你想保留它,我也会将
transpose
排除在外

keys = transpose $ f 16 $ f 8 $ f 4 $ f 2 $ f 1 $ transpose key
  where
    f rc [a, b, c, d] =
      let e = schedule rc d
          a' = zipWith xor a e
          b' = zipWith xor b a'
          c' = zipWith xor c b'
          d' = zipWith xor c c'
      in [a', b', c', d']  -- Here is where one may recognize `scanl` or a fold.
至于
schedule
,它是一个函数,它取最后一列(
d
以上,
last tW
以下)并将其置乱(
e
以上,
w'
以下)。您可以从
xpndD
的定义中提取它:

xpndD rc ws = take 3 tW ++ [w']
 where
  w' = zipWith xor (map sub w) [rc, 0, 0, 0]
  tW = transpose ws
  w  = take 4 $ tail $ cycle $ last tW
我们得到(以纯粹的表面重写为模,取4$tail$cycle d=tail d++[head d]):


你能生成一个完整的、可编译的测试用例吗?片段在这里不是很有帮助。令人高兴的是!我添加了一个编译和演示问题的最小版本。感谢关于模式匹配的提示…但是你能详细说明我应该如何重新定义
xpndC
,如果我已经扔掉了我应该
xor的专栏吗第四栏是?我也很想使用scanl
,但我不知道如何将schedule_core的C代码翻译成Haskell。我知道这要求很高,但我能在上下文中更多地了解这些想法吗?我得到的印象是,需要进行非琐碎的重构。一个奇妙的答案-我特别赞赏除了解释更优雅的扫描外,还吃了“快速修复”。谢谢!很高兴你喜欢它!哇,挖掘了一些相当复杂的代码并调试了它,这真是太好了
keys = transpose $ f 16 $ f 8 $ f 4 $ f 2 $ f 1 $ transpose key
  where
    f rc [a, b, c, d] =
      let e = schedule rc d
          a' = zipWith xor a e
          b' = zipWith xor b a'
          c' = zipWith xor c b'
          d' = zipWith xor c c'
      in [a', b', c', d']  -- Here is where one may recognize `scanl` or a fold.
xpndD rc ws = take 3 tW ++ [w']
 where
  w' = zipWith xor (map sub w) [rc, 0, 0, 0]
  tW = transpose ws
  w  = take 4 $ tail $ cycle $ last tW
schedule rc d = zipWith xor (map sub $ tail d ++ [head d]) [rc, 0, 0, 0]