commit 706563d1fa30a3bd75f94e6987b90860f8fa522a
parent 28d78912500b58309199ad07aa216081a23e97c7
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 30 Jul 2023 12:02:55 -0230
Add 3.22.
Diffstat:
4 files changed, 108 insertions(+), 0 deletions(-)
diff --git a/cryptopals.cabal b/cryptopals.cabal
@@ -159,3 +159,14 @@ executable pkcs7
, optparse-applicative
, text
+executable mt19937
+ main-is: MT19937.hs
+ ghc-options: -Wall -O2
+ default-language: Haskell2010
+ hs-source-dirs: src
+ build-depends:
+ base
+ , cryptopals
+ , optparse-applicative
+ , text
+
diff --git a/docs/s3.md b/docs/s3.md
@@ -122,3 +122,46 @@ the implementations he cites return signed 32-bit integers, but I
use (unsigned) Word32. One can convert results to e.g. Int32 with
fromIntegral to verify.
+There's also a binary:
+
+ $ mt19937 42 3
+ 1608637542
+ 3421126067
+ 4083286876
+
+#### 3.22
+
+After the fourth or fifth time my children woke me up in the middle of
+the night, I decided to just get up and pick at this stuff. I kicked off
+this business somewhere around 5-6am:
+
+ $ sleep $(shuf -i 40-1000 -n 1); ts=$(date +%s); \
+ sleep $(shuf -i 40-1000 -n 1); mt19937 $ts 1
+ 1133750118
+
+and then lay down again and fell asleep for a few hours. Using [this
+timestamp calculator](https://www.unixtimestamp.com/) after the fact,
+the timestamp is probably somewhere in the range of about \[1690702400,
+1690708000\]. So, using:
+
+ #!/usr/bin/env bash
+ declare -i i
+ i=1690702400
+ while (($i < 1690708000)); do
+ val=$(mt19937 $i 1)
+ if (($val == 1133750118)); then
+ echo "seed is $i"
+ exit
+ else
+ i+=1
+ fi
+ done
+
+we get:
+
+ $ ./crackmt.sh
+ seed is 1690706100
+
+So, via the same timestamp calculator, it was seeded at Sun Jul 30 2023
+06:05:00 GMT-0230 (heure d’été de Terre-Neuve).
+
diff --git a/etc/crackmt.sh b/etc/crackmt.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+declare -i i
+i=1690702400
+while (($i < 1690708000)); do
+ val=$(mt19937 $i 1)
+ echo "seed: $i, val: $val"
+ if (($val == 1133750118)); then
+ echo "seed is $i"
+ exit
+ else
+ i+=1
+ fi
+done
+
diff --git a/src/MT19937.hs b/src/MT19937.hs
@@ -0,0 +1,40 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+
+module Main where
+
+import qualified Cryptopals.Stream.RNG.MT19937 as MT
+import qualified Data.Text as T
+import qualified Data.Text.IO as TIO
+import Data.Foldable (for_)
+import GHC.Word (Word32)
+import qualified Options.Applicative as O
+
+data Args = Args {
+ argsSeed :: Word32
+ , argsBytes :: Word32
+ }
+
+ops :: O.Parser Args
+ops = Args
+ <$> O.argument O.auto (O.metavar "SEED")
+ <*> O.argument O.auto (O.metavar "BYTES")
+
+mt :: Args -> IO ()
+mt Args {..} = do
+ let gen = MT.seed argsSeed
+ (bytes, _) = MT.bytes (fromIntegral argsBytes) gen
+
+ for_ bytes $ TIO.putStrLn . T.pack . show
+
+main :: IO ()
+main = do
+ let pars = O.info (O.helper <*> ops) $
+ O.fullDesc
+ <> O.progDesc "generate random bytes from a Mersenne Twister"
+ <> O.header "mt19937"
+
+ args <- O.execParser pars
+
+ mt args
+