Cet*_*ert 0 performance haskell openssl wolfram-mathematica rsa
注意: 对于那些无法做出比无聊,无知的评论甚至是关闭有效问题的建议更好的人,请在此处查看接受的答案:使用GNU/Linux系统调用`splice`进行零拷贝Socket to Socket Haskell中的数据传输是如何为那些真正寻求建设性答案的人提供适当帮助的一个很好的例子!
嗨,我刚刚阅读PowerMod了Mathematica 8的文档,想要测试Haksell RSA包(ghc --make -O2 -O3 -fllvm -optlo-O3 test.hs):
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad
import System.Random
import Codec.Crypto.RSA
import Data.ByteString.Lazy
import Data.ByteString.Char8
import Criterion.Main
import Criterion.Config
main :: IO ()
main = do
print m1
print m4
print m8
defaultMainWith defaultConfig (return ()) [
bgroup "RSA" [
bench "1" $ ed m1
, bench "4" $ ed m4
, bench "8" $ ed m8
]
]
m1 = fromChunks [ Data.ByteString.Char8.replicate (1*1024) '0' ]
m4 = fromChunks [ Data.ByteString.Char8.replicate (4*1024) '0' ]
m8 = fromChunks [ Data.ByteString.Char8.replicate (8*1024) '0' ]
ed m = do
g1 <- newStdGen
let (el,il,g2) = generateKeyPair g1 1024
loop 1 g2 el il m
loop :: RandomGen g => Int -> g -> PublicKey -> PrivateKey -> Data.ByteString.Lazy.ByteString -> IO ()
loop n g e i m = do
let nn = n-1
let (em,ng) = encrypt g e m
let dm = decrypt i em
when (m == dm) $ Data.ByteString.Char8.putStr "1"
when (nn > 0 ) $ loop nn ng e i m
Run Code Online (Sandbox Code Playgroud)
也在Mathematica中试过这个:
{p, q} = Prime[RandomInteger[{10^4, 10^5}, {2}]];
{p, q, n = p q}
\[Lambda] = CarmichaelLambda[n]
d = NestWhile[#1 + 1 & , Round[n/3], GCD[\[Lambda], #1] =!= 1 &]
e = PowerMod[d, -1, \[Lambda]]
enc = PowerMod[#, e, n] &;
dec = PowerMod[#, d, n] &;
c = ConstantArray[48, 8 1024];
t = Table[c // enc // dec; // AbsoluteTiming, {10}][[All, 1]]
Run Code Online (Sandbox Code Playgroud)
Haskell(m8)和Mathematica案例中的计时相似:
{0.313015, 0.302337, 0.303766, 0.303321, 0.303018, 0.302574, \
0.302511, 0.303958, 0.301411, 0.300820}
Run Code Online (Sandbox Code Playgroud)
对于RSA,每8192字节长消息300ms是否可接受?OpenSSL或其他实现如何比较?
(测试台:64位linux; 4xCORE,Intel(R)Core(TM)i5 CPU M 430 @ 2.27GHz)
首先,好问题 - RSA与OpenSSL的性能差异也是我的一个问题.也就是说,这里有一堆文字没有给出答案.
Haskell RSA包已更改
我最近将RSA移到了使用CryptoRandomGen中RandomGen.您使用的速度很慢,StdGen因此切换到intel-aes软件包中的生成器或HashDRBGDRBG软件包中的(可能是缓冲版本)将有所帮助.
这不是你应该如何使用公钥加密
通常,您使用公钥来交换密钥或加密密钥,以便只有收件人才能对其进行解密.您似乎打算使用RSA来持续加密消息流.RSA的表现很少受到人们的关注,因为它是如此罕见的操作.
适当的基准测试
正如Daniel所说,您目前正在批量生成密钥生成,加密和解密基准.你回答说你不会生成很多密钥,只需要进行大量的enc/dec操作......所以你不认为你应该修复基准测试吗?
此外,你的基准似乎不完整,因而怀疑 - 至少它缺少一个导入.
其他令人震惊的事情
你说"目前关键对的随机数并不重要." 在它们很重要之前,没有理由为加密而烦恼.
基准测试 Oli也有一个好点.基准测试OpenSSL是可行的方法.
从命令行开始(就我所说的部分答案而言),OpenSSL强制您半正确地使用RSA,因此我们只是对真正小文件的加密进行基准测试:
dd if=/dev/urandom of=64B bs=64 count=1
openssl genrsa -out test.key 1024
openssl rsa -in test.key -out public.pem -outform PEM -pubout
openssl rsa -in test.key -out private.pem -outform PEM
time openssl rsautl -raw -ssl -encrypt -inkey private.pem -in 64B -out 64B.enc
Run Code Online (Sandbox Code Playgroud)
这给了我们5到12毫秒的任何地方.
现在为Haskell.除了化妆品的变化之外,我已经使用CryptoRandomGen和不那么快但OK的HashDRBG生成器转移到新的RSA,同时使您的加密功能纯净,并且放弃了不必要的比较.我们最终得到:
import Criterion.Main
import Criterion.Config
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
import Codec.Crypto.RSA
import Crypto.Random.DRBG
main :: IO ()
main = do
r1 <- newGenIO :: IO HashDRBG
r2 <- newGenIO :: IO (GenBuffered HashDRBG)
-- We don't care about the performance of generate, so we do it outside the benchmark framework
let (pub,priv,g2) = generateKeyPair r2 1024
defaultMainWith defaultConfig (return ()) [
bgroup "RSA" [
bench "1" $ whnf (enc r1 pub priv) m1
, bench "2" $ whnf (enc r2 pub priv) m1
]
]
m1 :: L.ByteString
m1 = L.pack [0..63]
enc :: CryptoRandomGen g => g -> PublicKey -> PrivateKey -> L.ByteString -> L.ByteString
enc g pub priv m =
let (em,ng) = encrypt g pub m
dm = decrypt priv em
in dm
Run Code Online (Sandbox Code Playgroud)
这产生大约3.5ms的测量值(用GHC 7.4和-O2编译).要明确:我不是说RSA比OpenSSL更快 - OpenSSL测试有更多的开销(加载可执行文件,读取密钥,读取明文,加密,写入结果)并且非常可信地可能是一个命令比RSA包更快.我所说的是"嘿看,Haskell RSA代码任意快速地执行到我并不关心的程度,如果你愿意,你可以更好地完善基准测试."
作为参考,openssl speed rsa1024它表示在0.5毫秒内签名(显然在我的机器上),我怀疑这是一个16字节的RSA加密以及其他操作.