Be a little bit more careful about what items we do and don't include, start adding modular math into the system.
This commit is contained in:
273
generate.hs
273
generate.hs
@@ -10,56 +10,105 @@ import System.FilePath((</>))
|
|||||||
import System.IO(Handle,IOMode(WriteMode),hPutStrLn,withFile,hFlush,hPutStr,stderr)
|
import System.IO(Handle,IOMode(WriteMode),hPutStrLn,withFile,hFlush,hPutStr,stderr)
|
||||||
import System.Random(StdGen,newStdGen,random,split)
|
import System.Random(StdGen,newStdGen,random,split)
|
||||||
|
|
||||||
data Level = Base | DivMul | Barrett
|
data Operation = Add
|
||||||
|
| BaseOps
|
||||||
|
| Barretts
|
||||||
|
| Div
|
||||||
|
| ModExp
|
||||||
|
| ModMul
|
||||||
|
| ModSq
|
||||||
|
| Mul
|
||||||
|
| Shifts
|
||||||
|
| Sub
|
||||||
|
| Convert Int
|
||||||
deriving (Eq, Ord, Show)
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
data Requirement = Req Int Operation
|
||||||
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
data Need = Need Operation (Int -> [Requirement])
|
||||||
|
|
||||||
|
needs :: [Need]
|
||||||
|
needs = [ Need ModExp (\ size -> [Req size ModMul
|
||||||
|
,Req size ModSq
|
||||||
|
,Req size Barretts])
|
||||||
|
, Need ModSq (\ size -> [Req (size * 2) Div
|
||||||
|
,Req size Barretts])
|
||||||
|
, Need ModMul (\ size -> [Req size Mul
|
||||||
|
,Req size Barretts
|
||||||
|
,Req size (Convert (size * 2))
|
||||||
|
,Req (size * 2) Div])
|
||||||
|
, Need Barretts (\ size -> [Req (size + 64) BaseOps
|
||||||
|
,Req size (Convert (size + 64))
|
||||||
|
,Req (size + 64) (Convert ((size * 2) + 64))
|
||||||
|
,Req size (Convert ((size * 2) + 64))
|
||||||
|
,Req ((size * 2) + 64) Add
|
||||||
|
,Req ((size * 2) + 64) Sub
|
||||||
|
,Req (size + 64) Mul
|
||||||
|
,Req (size * 2) (Convert ((size * 2) + 64))
|
||||||
|
,Req ((size * 2) + 64) Shifts
|
||||||
|
,Req ((size * 2) + 64) Div
|
||||||
|
,Req (size + 64) (Convert (size * 2))
|
||||||
|
,Req ((size * 2) + 64)
|
||||||
|
(Convert ((size * 2) + 128))
|
||||||
|
])
|
||||||
|
, Need Div (\ size -> [Req size (Convert (size * 2))
|
||||||
|
,Req 192 BaseOps
|
||||||
|
,Req 384 BaseOps
|
||||||
|
,Req 192 Mul
|
||||||
|
,Req size Mul
|
||||||
|
,Req size Shifts
|
||||||
|
,Req (size * 2) Sub
|
||||||
|
])
|
||||||
|
, Need Mul (\ size -> [Req (size * 2) BaseOps])
|
||||||
|
, Need Sub (\ size -> [Req size Add])
|
||||||
|
, Need Add (\ size -> [Req (size + 64) BaseOps
|
||||||
|
,Req size (Convert (size + 64))])
|
||||||
|
]
|
||||||
|
|
||||||
|
newRequirements :: Requirement -> [Requirement]
|
||||||
|
newRequirements (Req size op) = concatMap go needs ++ [Req size BaseOps]
|
||||||
|
where
|
||||||
|
go (Need op2 generator) | op == op2 = generator size
|
||||||
|
| otherwise = []
|
||||||
|
|
||||||
bitSizes :: [Int]
|
bitSizes :: [Int]
|
||||||
bitSizes = [192,256,384,512,576,1024,2048,3072,4096,7680,8192,15360]
|
bitSizes = [192,256,384,512,576,1024,2048,3072,4096,7680,8192,15360]
|
||||||
|
|
||||||
|
baseRequirements :: [Requirement]
|
||||||
|
baseRequirements = map (\ x -> Req x ModExp) bitSizes
|
||||||
|
|
||||||
|
requirements :: [Requirement]
|
||||||
|
requirements = go baseRequirements
|
||||||
|
where
|
||||||
|
step ls = let news = concatMap newRequirements ls
|
||||||
|
destBits = concatMap destRequirements (news ++ ls)
|
||||||
|
in ls ++ news ++ destBits
|
||||||
|
--
|
||||||
|
go ls = let ls' = removeDups (sort (step ls))
|
||||||
|
in if ls == ls' then ls else go ls'
|
||||||
|
--
|
||||||
|
removeDups [] = []
|
||||||
|
removeDups (x:xs) | x `elem` xs = removeDups xs
|
||||||
|
| otherwise = x : removeDups xs
|
||||||
|
--
|
||||||
|
destRequirements (Req _ (Convert t)) = [Req t BaseOps]
|
||||||
|
destRequirements _ = []
|
||||||
|
|
||||||
numberOfTests :: Int
|
numberOfTests :: Int
|
||||||
numberOfTests = 1000
|
numberOfTests = 1000
|
||||||
|
|
||||||
baseMap :: Map.Map Int Level
|
generateTestBlock :: Handle ->
|
||||||
baseMap = foldr (\ s m -> Map.insert s Barrett m) Map.empty bitSizes
|
String -> Operation -> Bool -> [Int -> Int] ->
|
||||||
|
IO ()
|
||||||
smartInsert :: Int -> Level -> Map.Map Int Level -> Map.Map Int Level
|
|
||||||
smartInsert size level map = Map.insertWith max size level map
|
|
||||||
|
|
||||||
generateNext :: Int -> Level -> Map.Map Int Level -> Map.Map Int Level
|
|
||||||
generateNext size Base acc = acc
|
|
||||||
generateNext size DivMul acc = smartInsert (size + 64) Base $
|
|
||||||
smartInsert (size * 2) Base $
|
|
||||||
acc
|
|
||||||
generateNext size Barrett acc = smartInsert (size + 64) Base $
|
|
||||||
smartInsert (size * 2) Base $
|
|
||||||
smartInsert ( size + 64) DivMul $
|
|
||||||
smartInsert ((size * 2) + 64) DivMul $
|
|
||||||
acc
|
|
||||||
|
|
||||||
step :: Map.Map Int Level -> Map.Map Int Level
|
|
||||||
step m = Map.foldrWithKey generateNext m m
|
|
||||||
|
|
||||||
fixpoint :: Map.Map Int Level -> Map.Map Int Level
|
|
||||||
fixpoint m | m == m' = m
|
|
||||||
| otherwise = fixpoint m'
|
|
||||||
where m' = step m
|
|
||||||
|
|
||||||
finalMap :: Map.Map Int Level
|
|
||||||
finalMap = fixpoint baseMap
|
|
||||||
|
|
||||||
conversions :: [Int] -> [(Int,Int)]
|
|
||||||
conversions [] = []
|
|
||||||
conversions (x:rest) = (map (\ y -> (x,y)) rest) ++ conversions rest
|
|
||||||
|
|
||||||
generateTestBlock :: Handle -> String -> Level -> Bool -> [Int -> Int] -> IO ()
|
|
||||||
generateTestBlock hndl name level useRT addOns =
|
generateTestBlock hndl name level useRT addOns =
|
||||||
do hPutStrLn hndl (" mod " ++ name ++ " {")
|
do hPutStrLn hndl (" mod " ++ name ++ " {")
|
||||||
when useRT $
|
when useRT $
|
||||||
do hPutStrLn hndl (" use super::super::*;")
|
do hPutStrLn hndl (" use super::super::*;")
|
||||||
hPutStrLn hndl (" use testing::run_test;")
|
hPutStrLn hndl (" use testing::run_test;")
|
||||||
hPutStrLn hndl ""
|
hPutStrLn hndl ""
|
||||||
forM_ (sort (Map.toList finalMap)) $ \ (size, kind) ->
|
forM_ requirements $ \ (Req size kind) ->
|
||||||
when (kind >= level) $
|
when (kind == level) $
|
||||||
hPutStrLn hndl (" generate_" ++ name ++
|
hPutStrLn hndl (" generate_" ++ name ++
|
||||||
"_tests!(U" ++ show size ++ ", " ++
|
"_tests!(U" ++ show size ++ ", " ++
|
||||||
"u" ++ show size ++
|
"u" ++ show size ++
|
||||||
@@ -70,64 +119,70 @@ generateTestBlock hndl name level useRT addOns =
|
|||||||
generateInvocs :: IO ()
|
generateInvocs :: IO ()
|
||||||
generateInvocs =
|
generateInvocs =
|
||||||
withFile "src/unsigned/invoc.rs" WriteMode $ \ hndl ->
|
withFile "src/unsigned/invoc.rs" WriteMode $ \ hndl ->
|
||||||
do forM_ (sort (Map.toList finalMap)) $ \ item ->
|
do forM_ requirements $ \ (Req size oper) ->
|
||||||
case item of
|
case oper of
|
||||||
(size, Base) ->
|
Add -> hPutStrLn hndl ("addition_impls!(U" ++ show size ++ ", U" ++ show (size + 64) ++ ");")
|
||||||
hPutStrLn hndl ("generate_number!(U" ++ show size ++ ", " ++
|
BaseOps -> hPutStrLn hndl ("base_impls!(U" ++ show size ++ ", " ++ show (size `div` 64) ++ ");")
|
||||||
show (size `div` 64) ++ ");")
|
Barretts -> hPutStrLn hndl ("barrett_impl!(BarrettU" ++ show size ++ ", U" ++ show size ++ ", U" ++ show (size + 64) ++ ", U" ++ show (size * 2) ++ ", U" ++ show ((size * 2) + 64) ++ ");")
|
||||||
(size, DivMul) ->
|
Div -> hPutStrLn hndl ("div_impls!(U" ++ show size ++ ", U" ++ show (size * 2) ++ ");")
|
||||||
hPutStrLn hndl ("generate_number!(U" ++ show size ++ ", " ++
|
ModExp -> hPutStrLn hndl ("modexp_impls!(U" ++ show size ++ ");")
|
||||||
show (size `div` 64) ++ ", U" ++
|
ModMul -> hPutStrLn hndl ("modmul_impls!(U" ++ show size ++ ", U" ++ show (size * 2) ++ ");")
|
||||||
show (size + 64) ++ ", U" ++
|
ModSq -> hPutStrLn hndl ("modsq_impls!(U" ++ show size ++ ");")
|
||||||
show (size * 2) ++ ");")
|
Mul -> hPutStrLn hndl ("multiply_impls!(U" ++ show size ++ ", U" ++ show (size * 2) ++ ");")
|
||||||
(size, Barrett) ->
|
Shifts -> hPutStrLn hndl ("shift_impls!(U" ++ show size ++ ", " ++ show (size `div` 64) ++ ");")
|
||||||
hPutStrLn hndl ("generate_number!(U" ++ show size ++ ", " ++
|
Sub -> hPutStrLn hndl ("subtraction_impls!(U" ++ show size ++ ", " ++ show (size `div` 64) ++ ");")
|
||||||
show (size `div` 64) ++ ", U" ++
|
Convert to -> hPutStrLn hndl ("conversion_impls!(U" ++ show size ++ ", U" ++ show to ++ ");")
|
||||||
show (size + 64) ++ ", U" ++
|
|
||||||
show (size * 2) ++ ", U" ++
|
|
||||||
show ((size * 2) + 64) ++ ", BarrettU" ++
|
|
||||||
show size ++ ");")
|
|
||||||
hPutStrLn hndl ""
|
hPutStrLn hndl ""
|
||||||
forM_ (conversions (Map.keys finalMap)) $ \ (a,b) ->
|
|
||||||
hPutStrLn hndl ("conversion_impls!(U" ++ show a ++ ", " ++
|
|
||||||
"U" ++ show b ++ ");")
|
|
||||||
hPutStrLn hndl "\n#[cfg(test)]"
|
hPutStrLn hndl "\n#[cfg(test)]"
|
||||||
hPutStrLn hndl "mod tests {"
|
hPutStrLn hndl "mod tests {"
|
||||||
generateTestBlock hndl "base" Base True []
|
generateTestBlock hndl "base" BaseOps True []
|
||||||
generateTestBlock hndl "conversion" Base False []
|
generateTestBlock hndl "conversion" BaseOps False []
|
||||||
generateTestBlock hndl "codec" Base False []
|
generateTestBlock hndl "codec" BaseOps False []
|
||||||
generateTestBlock hndl "cmp" Base True []
|
generateTestBlock hndl "cmp" BaseOps True []
|
||||||
generateTestBlock hndl "sub" Base True []
|
generateTestBlock hndl "sub" Sub True []
|
||||||
generateTestBlock hndl "shiftl" Base True []
|
generateTestBlock hndl "shiftl" Shifts True []
|
||||||
generateTestBlock hndl "shiftr" Base True []
|
generateTestBlock hndl "shiftr" Shifts True []
|
||||||
generateTestBlock hndl "add" DivMul True [(+ 64)]
|
generateTestBlock hndl "add" Add True [(+ 64)]
|
||||||
generateTestBlock hndl "mul" DivMul True [(* 2)]
|
generateTestBlock hndl "mul" Mul True [(* 2)]
|
||||||
generateTestBlock hndl "div" DivMul True []
|
generateTestBlock hndl "div" Div True []
|
||||||
generateTestBlock hndl "barrett_gen" Barrett True [(+ 64)]
|
generateTestBlock hndl "barrett_gen" Barretts True [(+ 64)]
|
||||||
generateTestBlock hndl "barrett_red" Barrett True [(+ 64), (* 2)]
|
generateTestBlock hndl "barrett_red" Barretts True [(+ 64), (* 2)]
|
||||||
hPutStrLn hndl "}"
|
hPutStrLn hndl "}"
|
||||||
|
|
||||||
log :: String -> IO ()
|
log :: String -> IO ()
|
||||||
log str = hPutStr stderr str >> hFlush stderr
|
log str = hPutStr stderr str >> hFlush stderr
|
||||||
|
|
||||||
generateTests :: Level -> String -> a -> (Int -> a -> (Map.Map String String, a)) -> IO ()
|
generateTests :: Operation -> String -> Database ->
|
||||||
generateTests minLevel directory init runner =
|
(Int -> Database -> (Map.Map String String, Integer, Database)) ->
|
||||||
forM_ (sort (Map.toList finalMap)) $ \ (size, myLevel) ->
|
IO ()
|
||||||
when (myLevel >= minLevel) $
|
generateTests op directory init runner = do
|
||||||
do createDirectoryIfMissing True ("testdata" </> directory)
|
forM_ (getSizes op requirements) $ \ size ->
|
||||||
log $ "Generating " ++ show size ++ "-bit " ++ directory ++ " tests "
|
do createDirectoryIfMissing True ("testdata" </> directory)
|
||||||
let dest = "testdata" </> directory </> ("U" ++ show size ++ ".tests")
|
log $ "Generating " ++ show size ++ "-bit " ++ directory ++ " tests: 000%"
|
||||||
withFile dest WriteMode $ \ hndl ->
|
let dest = "testdata" </> directory </> ("U" ++ show size ++ ".tests")
|
||||||
foldM_ (writer hndl size runner) init [0..numberOfTests]
|
withFile dest WriteMode $ \ hndl ->
|
||||||
log "done.\n"
|
foldM_ (writer hndl size runner) init [0..numberOfTests]
|
||||||
|
log "\n"
|
||||||
where
|
where
|
||||||
writer :: Handle -> Int -> (Int -> a -> (Map.Map String String, a)) -> a -> Int -> IO a
|
getSizes :: Operation -> [Requirement] -> [Int]
|
||||||
writer hndl size runner input _ =
|
getSizes _ [] = []
|
||||||
do let (output, acc) = runner size input
|
getSizes oper ((Req size oper2) : rest)
|
||||||
forM_ (Map.toList output) $ \ (key, val) ->
|
| oper == oper2 = size : getSizes oper rest
|
||||||
do hPutStrLn hndl (key ++ ": " ++ val)
|
| otherwise = getSizes oper rest
|
||||||
log "."
|
--
|
||||||
return acc
|
writer hndl size runner db x =
|
||||||
|
do let (output, key, acc@(db',_)) = runner size db
|
||||||
|
before = Map.findWithDefault [] "RESULT" db'
|
||||||
|
if length (filter (== key) before) >= 10
|
||||||
|
then writer hndl size runner acc x
|
||||||
|
else do forM_ (Map.toList output) $ \ (key, val) ->
|
||||||
|
do hPutStrLn hndl (key ++ ": " ++ val)
|
||||||
|
let val = (x * 100) `div` numberOfTests
|
||||||
|
log ("\b\b\b\b" ++ pad 3 ' ' (show val) ++ "%")
|
||||||
|
return acc
|
||||||
|
--
|
||||||
|
pad x c str | length str < x = pad x c (c : str)
|
||||||
|
| otherwise = str
|
||||||
|
|
||||||
type Database = (Map.Map String [Integer], StdGen)
|
type Database = (Map.Map String [Integer], StdGen)
|
||||||
|
|
||||||
@@ -173,19 +228,23 @@ generateAllTheTests :: IO ()
|
|||||||
generateAllTheTests =
|
generateAllTheTests =
|
||||||
do gen0 <- newStdGen
|
do gen0 <- newStdGen
|
||||||
let (db1, gen1) = emptyDatabase gen0
|
let (db1, gen1) = emptyDatabase gen0
|
||||||
generateTests DivMul "add" db1 $ \ size memory0 ->
|
generateTests Add "add" db1 $ \ size memory0 ->
|
||||||
let (a, memory1) = generateNum memory0 "a" size
|
let (a, memory1) = generateNum memory0 "a" size
|
||||||
(b, memory2) = generateNum memory1 "b" size
|
(b, memory2) = generateNum memory1 "b" size
|
||||||
c = a + b
|
c = a + b
|
||||||
in (Map.fromList [("a", showX a), ("b", showX b),("c", showX c)], memory2)
|
res = Map.fromList [("a", showX a), ("b", showX b),
|
||||||
|
("c", showX c)]
|
||||||
|
in (res, c, memory2)
|
||||||
let (db2, gen2) = emptyDatabase gen1
|
let (db2, gen2) = emptyDatabase gen1
|
||||||
generateTests Barrett "barrett_gen" db2 $ \ size memory0 ->
|
generateTests Barretts "barrett_gen" db2 $ \ size memory0 ->
|
||||||
let (m, memory1) = generateNum memory0 "m" size
|
let (m, memory1) = generateNum memory0 "m" size
|
||||||
k = computeK m
|
k = computeK m
|
||||||
u = barrett m
|
u = barrett m
|
||||||
in (Map.fromList [("m", showX m), ("k", showX k), ("u", showX u)],memory1)
|
res = Map.fromList [("m", showX m), ("k", showX k),
|
||||||
|
("u", showX u)]
|
||||||
|
in (res, u, memory1)
|
||||||
let (db3, gen3) = emptyDatabase gen1
|
let (db3, gen3) = emptyDatabase gen1
|
||||||
generateTests Barrett "barrett_reduce" db3 $ \ size memory0 ->
|
generateTests Barretts "barrett_reduce" db3 $ \ size memory0 ->
|
||||||
let (m, memory1) = generateNum memory0 "m" size
|
let (m, memory1) = generateNum memory0 "m" size
|
||||||
(x, memory2) = generateNum memory1 "x" (min size (2 * k * 64))
|
(x, memory2) = generateNum memory1 "x" (min size (2 * k * 64))
|
||||||
k = computeK m
|
k = computeK m
|
||||||
@@ -194,9 +253,9 @@ generateAllTheTests =
|
|||||||
res = Map.fromList [("m", showX m), ("x", showX x),
|
res = Map.fromList [("m", showX m), ("x", showX x),
|
||||||
("k", showX k), ("u", showX u),
|
("k", showX k), ("u", showX u),
|
||||||
("r", showX r)]
|
("r", showX r)]
|
||||||
in (res, memory2)
|
in (res, r, memory2)
|
||||||
let (db4, gen4) = emptyDatabase gen2
|
let (db4, gen4) = emptyDatabase gen2
|
||||||
generateTests Base "base" db4 $ \ size memory0 ->
|
generateTests BaseOps "base" db4 $ \ size memory0 ->
|
||||||
let (x, memory1) = generateNum memory0 "x" size
|
let (x, memory1) = generateNum memory0 "x" size
|
||||||
(m, memory2) = generateNum memory1 "m" size
|
(m, memory2) = generateNum memory1 "m" size
|
||||||
m' = m `mod` (fromIntegral size `div` 64)
|
m' = m `mod` (fromIntegral size `div` 64)
|
||||||
@@ -204,58 +263,60 @@ generateAllTheTests =
|
|||||||
res = Map.fromList [("x", showX x), ("z", showB (x == 0)),
|
res = Map.fromList [("x", showX x), ("z", showB (x == 0)),
|
||||||
("e", showB (even x)), ("o", showB (odd x)),
|
("e", showB (even x)), ("o", showB (odd x)),
|
||||||
("m", showX m'), ("r", showX r)]
|
("m", showX m'), ("r", showX r)]
|
||||||
in (res, memory2)
|
in (res, x, memory2)
|
||||||
let (db5, gen5) = emptyDatabase gen3
|
let (db5, gen5) = emptyDatabase gen3
|
||||||
generateTests Base "cmp" db5 $ \ size memory0 ->
|
generateTests BaseOps "cmp" db5 $ \ size memory0 ->
|
||||||
let (a, memory1) = generateNum memory0 "a" size
|
let (a, memory1) = generateNum memory0 "a" size
|
||||||
(b, memory2) = generateNum memory1 "b" size
|
(b, memory2) = generateNum memory1 "b" size
|
||||||
res = Map.fromList [("a", showX a), ("b", showX b),
|
res = Map.fromList [("a", showX a), ("b", showX b),
|
||||||
("g", showB (a > b)), ("l", showB (a < b)),
|
("g", showB (a > b)), ("l", showB (a < b)),
|
||||||
("e", showB (a == b))]
|
("e", showB (a == b))]
|
||||||
in (res, memory2)
|
in (res, a, memory2)
|
||||||
let (db6, gen6) = emptyDatabase gen4
|
let (db6, gen6) = emptyDatabase gen4
|
||||||
generateTests DivMul "div" db6 $ \ size memory0 ->
|
generateTests Div "div" db6 $ \ size memory0 ->
|
||||||
let (a, memory1) = generateNum memory0 "a" size
|
let (a, memory1) = generateNum memory0 "a" size
|
||||||
(b, memory2) = generateNum memory1 "b" size
|
(b, memory2) = generateNum memory1 "b" size
|
||||||
q = a `div` b
|
q = a `div` b
|
||||||
r = a `mod` b
|
r = a `mod` b
|
||||||
res = Map.fromList [("a", showX a), ("b", showX b),
|
res = Map.fromList [("a", showX a), ("b", showX b),
|
||||||
("q", showX q), ("r", showX r)]
|
("q", showX q), ("r", showX r)]
|
||||||
in (res, memory2)
|
in (res, q, memory2)
|
||||||
let (db7, gen7) = emptyDatabase gen5
|
let (db7, gen7) = emptyDatabase gen5
|
||||||
generateTests DivMul "mul" db7 $ \ size memory0 ->
|
generateTests Mul "mul" db7 $ \ size memory0 ->
|
||||||
let (a, memory1) = generateNum memory0 "a" size
|
let (a, memory1) = generateNum memory0 "a" size
|
||||||
(b, memory2) = generateNum memory1 "b" size
|
(b, memory2) = generateNum memory1 "b" size
|
||||||
c = a * b
|
c = a * b
|
||||||
res = Map.fromList [("a", showX a), ("b", showX b),
|
res = Map.fromList [("a", showX a), ("b", showX b),
|
||||||
("c", showX c)]
|
("c", showX c)]
|
||||||
in (res, memory2)
|
in (res, c, memory2)
|
||||||
let (db8, gen8) = emptyDatabase gen6
|
let (db8, gen8) = emptyDatabase gen6
|
||||||
generateTests Base "shiftl" db8 $ \ size memory0 ->
|
generateTests Shifts "shiftl" db8 $ \ size memory0 ->
|
||||||
let (a, memory1) = generateNum memory0 "a" size
|
let (a, memory1) = generateNum memory0 "a" size
|
||||||
(l, memory2) = generateNum memory1 "l" size
|
(l, memory2) = generateNum memory1 "l" size
|
||||||
l' = l `mod` fromIntegral (computeK a * 64)
|
l' = l `mod` fromIntegral (computeK a * 64)
|
||||||
r = modulate (a `shiftL` fromIntegral l') size
|
r = modulate (a `shiftL` fromIntegral l') size
|
||||||
res = Map.fromList [("a", showX a), ("l", showX l'), ("r", showX r)]
|
res = Map.fromList [("a", showX a), ("l", showX l'), ("r", showX r)]
|
||||||
in (res, memory2)
|
in (res, r, memory2)
|
||||||
let (db9, gen9) = emptyDatabase gen6
|
let (db9, gen9) = emptyDatabase gen6
|
||||||
generateTests Base "shiftr" db9 $ \ size memory0 ->
|
generateTests Shifts "shiftr" db9 $ \ size memory0 ->
|
||||||
let (a, memory1) = generateNum memory0 "a" size
|
let (a, memory1) = generateNum memory0 "a" size
|
||||||
(l, memory2) = generateNum memory1 "l" size
|
(l, memory2) = generateNum memory1 "l" size
|
||||||
l' = l `mod` fromIntegral (computeK a * 64)
|
l' = l `mod` fromIntegral (computeK a * 64)
|
||||||
r = modulate (a `shiftR` fromIntegral l') size
|
r = modulate (a `shiftR` fromIntegral l') size
|
||||||
res = Map.fromList [("a", showX a), ("l", showX l'), ("r", showX r)]
|
res = Map.fromList [("a", showX a), ("l", showX l'), ("r", showX r)]
|
||||||
in (res, memory2)
|
in (res, l, memory2)
|
||||||
let (dbA, genA) = emptyDatabase gen7
|
let (dbA, genA) = emptyDatabase gen7
|
||||||
generateTests Base "sub" dbA $ \ size memory0 ->
|
generateTests Sub "sub" dbA $ \ size memory0 ->
|
||||||
let (a, memory1) = generateNum memory0 "a" size
|
let (a, memory1) = generateNum memory0 "a" size
|
||||||
(b, memory2) = generateNum memory1 "b" size
|
(b, memory2) = generateNum memory1 "b" size
|
||||||
c = modulate (a - b) size
|
c = modulate (a - b) size
|
||||||
in (Map.fromList [("a", showX a), ("b", showX b), ("c", showX c)], memory2)
|
res = Map.fromList [("a", showX a), ("b", showX b),
|
||||||
|
("c", showX c)]
|
||||||
|
in (res, c, memory2)
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main =
|
main =
|
||||||
do args <- getArgs
|
do args <- getArgs
|
||||||
let args' = if null args then ["invocs", "test"] else args
|
let args' = if null args then ["invocs", "tests"] else args
|
||||||
when ("invocs" `elem` args') generateInvocs
|
when ("invocs" `elem` args') generateInvocs
|
||||||
when ("tests" `elem` args') generateAllTheTests
|
when ("tests" `elem` args') generateAllTheTests
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,10 @@ mod div;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod formatter;
|
mod formatter;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
mod modexp;
|
||||||
|
#[macro_use]
|
||||||
|
mod modmul;
|
||||||
|
#[macro_use]
|
||||||
mod mul;
|
mod mul;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod shifts;
|
mod shifts;
|
||||||
@@ -27,6 +31,7 @@ use self::cmp::compare;
|
|||||||
use self::codec::{Encoder,Decoder,raw_decoder};
|
use self::codec::{Encoder,Decoder,raw_decoder};
|
||||||
use self::div::{DivMod,get_number_size};
|
use self::div::{DivMod,get_number_size};
|
||||||
use self::formatter::tochar;
|
use self::formatter::tochar;
|
||||||
|
use self::modmul::ModMul;
|
||||||
use self::mul::multiply;
|
use self::mul::multiply;
|
||||||
use self::shifts::{shiftl,shiftr};
|
use self::shifts::{shiftl,shiftr};
|
||||||
use self::sub::subtract;
|
use self::sub::subtract;
|
||||||
@@ -41,28 +46,20 @@ use std::ops::{Sub,SubAssign};
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use quickcheck::{Arbitrary,Gen};
|
use quickcheck::{Arbitrary,Gen};
|
||||||
|
|
||||||
macro_rules! generate_number
|
macro_rules! base_impls
|
||||||
{
|
{
|
||||||
($name: ident, $size: expr) => {
|
($name: ident, $size: expr) => {
|
||||||
generate_base!($name, $size);
|
generate_base!($name, $size);
|
||||||
generate_base_conversions!($name);
|
generate_base_conversions!($name);
|
||||||
generate_codec!($name);
|
generate_codec!($name);
|
||||||
generate_formatter!($name);
|
generate_formatter!($name);
|
||||||
|
|
||||||
cmp_impls!($name);
|
cmp_impls!($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
subtraction_impls!($name, $size);
|
macro_rules! modsq_impls
|
||||||
shift_impls!($name, $size);
|
{
|
||||||
};
|
($name: ident) => {
|
||||||
($name: ident, $size: expr, $plus1: ident, $times2: ident) => {
|
|
||||||
generate_number!($name, $size);
|
|
||||||
addition_impls!($name, $plus1);
|
|
||||||
multiply_impls!($name, $times2);
|
|
||||||
div_impls!($name, $times2);
|
|
||||||
};
|
|
||||||
($name: ident, $size: expr, $plus1: ident, $times2: ident, $big: ident, $bar: ident) => {
|
|
||||||
generate_number!($name, $size, $plus1, $times2);
|
|
||||||
barrett_impl!($bar, $name, $plus1, $times2, $big);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
39
src/unsigned/modexp.rs
Normal file
39
src/unsigned/modexp.rs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
pub trait ModExp<T> {
|
||||||
|
fn modexp(&self, e: &Self, m: &T) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! modexp_impls {
|
||||||
|
($name: ident) => {
|
||||||
|
// impl ModExp<$name> for $name {
|
||||||
|
// fn modexp(&self, e: &$name, m: &$name) -> $name {
|
||||||
|
// // S <- g
|
||||||
|
// let mut s = self.clone();
|
||||||
|
// // A <- 1
|
||||||
|
// let mut a = $name::from(1u64);
|
||||||
|
// // We do a quick skim through and find the highest index that
|
||||||
|
// // actually has a value in it.
|
||||||
|
// let mut e = ine.clone();
|
||||||
|
// // While e != 0 do the following:
|
||||||
|
// while e.values.iter().any(|x| *x != 0) {
|
||||||
|
// // If e is odd then A <- A * S
|
||||||
|
// if e.values[0] & 1 != 0 {
|
||||||
|
// a.modmul(&s, m);
|
||||||
|
// }
|
||||||
|
// // e <- floor(e / 2)
|
||||||
|
// let mut carry = 0;
|
||||||
|
// e.values.iter_mut().rev().for_each(|x| {
|
||||||
|
// let new_carry = *x & 1;
|
||||||
|
// *x = (*x >> 1) | (carry << 63);
|
||||||
|
// carry = new_carry;
|
||||||
|
// });
|
||||||
|
// // If e != 0 then S <- S * S
|
||||||
|
// s.modsq(m);
|
||||||
|
// }
|
||||||
|
// // Return A
|
||||||
|
// a
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
($name: ident, $barrett: ident) => {
|
||||||
|
};
|
||||||
|
}
|
||||||
16
src/unsigned/modmul.rs
Normal file
16
src/unsigned/modmul.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
pub trait ModMul<T> {
|
||||||
|
fn modmul(&self, x: &Self, m: &T) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! modmul_impls {
|
||||||
|
($name: ident, $dbl: ident) => {
|
||||||
|
impl ModMul<$name> for $name {
|
||||||
|
fn modmul(&self, x: &$name, m: &$name) -> $name {
|
||||||
|
let mulres = (self as &$name) * x;
|
||||||
|
let bigm = $dbl::from(m);
|
||||||
|
let (_, bigres) = mulres.divmod(&bigm);
|
||||||
|
$name::from(bigres)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
6006
testdata/add/U1024.tests
vendored
6006
testdata/add/U1024.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U1088.tests
vendored
6006
testdata/add/U1088.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U1152.tests
vendored
6006
testdata/add/U1152.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U1216.tests
vendored
6006
testdata/add/U1216.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U12288.tests
vendored
Normal file
3003
testdata/add/U12288.tests
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U12416.tests
vendored
6006
testdata/add/U12416.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U1280.tests
vendored
3003
testdata/add/U1280.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/shiftl/U2432.tests → testdata/add/U1536.tests
vendored
6006
testdata/shiftl/U2432.tests → testdata/add/U1536.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U15424.tests
vendored
6006
testdata/add/U15424.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U16384.tests
vendored
6006
testdata/add/U16384.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U16448.tests
vendored
6006
testdata/add/U16448.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U16512.tests
vendored
6006
testdata/add/U16512.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U1664.tests
vendored
6006
testdata/add/U1664.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U192.tests
vendored
3003
testdata/add/U192.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U2048.tests
vendored
6006
testdata/add/U2048.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U2112.tests
vendored
6006
testdata/add/U2112.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U2176.tests
vendored
6006
testdata/add/U2176.tests
vendored
File diff suppressed because it is too large
Load Diff
7007
testdata/div/U3136.tests → testdata/add/U2304.tests
vendored
7007
testdata/div/U3136.tests → testdata/add/U2304.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U2432.tests
vendored
6006
testdata/add/U2432.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U256.tests
vendored
3003
testdata/add/U256.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U3072.tests
vendored
3003
testdata/add/U3072.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U30720.tests
vendored
6006
testdata/add/U30720.tests
vendored
File diff suppressed because one or more lines are too long
6006
testdata/add/U30784.tests
vendored
6006
testdata/add/U30784.tests
vendored
File diff suppressed because one or more lines are too long
6006
testdata/add/U30848.tests
vendored
6006
testdata/add/U30848.tests
vendored
File diff suppressed because one or more lines are too long
3003
testdata/add/U3136.tests
vendored
3003
testdata/add/U3136.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U320.tests
vendored
3003
testdata/add/U320.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U3200.tests
vendored
3003
testdata/add/U3200.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U32768.tests
vendored
Normal file
3003
testdata/add/U32768.tests
vendored
Normal file
File diff suppressed because one or more lines are too long
6006
testdata/add/U32896.tests
vendored
6006
testdata/add/U32896.tests
vendored
File diff suppressed because one or more lines are too long
3003
testdata/add/U384.tests
vendored
3003
testdata/add/U384.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U4096.tests
vendored
6006
testdata/add/U4096.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U4160.tests
vendored
6006
testdata/add/U4160.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U4224.tests
vendored
6006
testdata/add/U4224.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U448.tests
vendored
6006
testdata/add/U448.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U512.tests
vendored
3003
testdata/add/U512.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U576.tests
vendored
6006
testdata/add/U576.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U6144.tests
vendored
3003
testdata/add/U6144.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U61440.tests
vendored
Normal file
3003
testdata/add/U61440.tests
vendored
Normal file
File diff suppressed because one or more lines are too long
6006
testdata/add/U61568.tests
vendored
6006
testdata/add/U61568.tests
vendored
File diff suppressed because one or more lines are too long
6006
testdata/add/U6208.tests
vendored
6006
testdata/add/U6208.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U6272.tests
vendored
3003
testdata/add/U6272.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U640.tests
vendored
3003
testdata/add/U640.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U704.tests
vendored
3003
testdata/add/U704.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U768.tests
vendored
6006
testdata/add/U768.tests
vendored
File diff suppressed because it is too large
Load Diff
3003
testdata/add/U7744.tests
vendored
3003
testdata/add/U7744.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U8192.tests
vendored
6006
testdata/add/U8192.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U8256.tests
vendored
6006
testdata/add/U8256.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U832.tests
vendored
6006
testdata/add/U832.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U8320.tests
vendored
6006
testdata/add/U8320.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/add/U896.tests
vendored
6006
testdata/add/U896.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U1024.tests
vendored
4384
testdata/barrett_gen/U1024.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U15360.tests
vendored
4384
testdata/barrett_gen/U15360.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U192.tests
vendored
4384
testdata/barrett_gen/U192.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U2048.tests
vendored
4384
testdata/barrett_gen/U2048.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U256.tests
vendored
4384
testdata/barrett_gen/U256.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U3072.tests
vendored
4384
testdata/barrett_gen/U3072.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U384.tests
vendored
4384
testdata/barrett_gen/U384.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U4096.tests
vendored
4384
testdata/barrett_gen/U4096.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U512.tests
vendored
4384
testdata/barrett_gen/U512.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U576.tests
vendored
4384
testdata/barrett_gen/U576.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U7680.tests
vendored
4384
testdata/barrett_gen/U7680.tests
vendored
File diff suppressed because it is too large
Load Diff
4384
testdata/barrett_gen/U8192.tests
vendored
4384
testdata/barrett_gen/U8192.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U1024.tests
vendored
10008
testdata/barrett_reduce/U1024.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U15360.tests
vendored
10008
testdata/barrett_reduce/U15360.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U192.tests
vendored
10008
testdata/barrett_reduce/U192.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U2048.tests
vendored
10008
testdata/barrett_reduce/U2048.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U256.tests
vendored
10008
testdata/barrett_reduce/U256.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U3072.tests
vendored
10008
testdata/barrett_reduce/U3072.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U384.tests
vendored
10008
testdata/barrett_reduce/U384.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U4096.tests
vendored
10008
testdata/barrett_reduce/U4096.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U512.tests
vendored
10008
testdata/barrett_reduce/U512.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U576.tests
vendored
10008
testdata/barrett_reduce/U576.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U7680.tests
vendored
10008
testdata/barrett_reduce/U7680.tests
vendored
File diff suppressed because it is too large
Load Diff
10008
testdata/barrett_reduce/U8192.tests
vendored
10008
testdata/barrett_reduce/U8192.tests
vendored
File diff suppressed because it is too large
Load Diff
11040
testdata/base/U1024.tests
vendored
11040
testdata/base/U1024.tests
vendored
File diff suppressed because it is too large
Load Diff
10824
testdata/base/U1088.tests
vendored
10824
testdata/base/U1088.tests
vendored
File diff suppressed because it is too large
Load Diff
10800
testdata/base/U1152.tests
vendored
10800
testdata/base/U1152.tests
vendored
File diff suppressed because it is too large
Load Diff
10584
testdata/base/U1216.tests
vendored
10584
testdata/base/U1216.tests
vendored
File diff suppressed because it is too large
Load Diff
9009
testdata/shiftl/U8320.tests → testdata/base/U12288.tests
vendored
9009
testdata/shiftl/U8320.tests → testdata/base/U12288.tests
vendored
File diff suppressed because it is too large
Load Diff
9009
testdata/sub/U6144.tests → testdata/base/U12352.tests
vendored
9009
testdata/sub/U6144.tests → testdata/base/U12352.tests
vendored
File diff suppressed because it is too large
Load Diff
11706
testdata/base/U12416.tests
vendored
11706
testdata/base/U12416.tests
vendored
File diff suppressed because it is too large
Load Diff
9009
testdata/sub/U6272.tests → testdata/base/U12480.tests
vendored
9009
testdata/sub/U6272.tests → testdata/base/U12480.tests
vendored
File diff suppressed because it is too large
Load Diff
10886
testdata/base/U1280.tests
vendored
10886
testdata/base/U1280.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/base/U1536.tests
vendored
Normal file
6006
testdata/base/U1536.tests
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11724
testdata/base/U15360.tests
vendored
11724
testdata/base/U15360.tests
vendored
File diff suppressed because it is too large
Load Diff
11568
testdata/base/U15424.tests
vendored
11568
testdata/base/U15424.tests
vendored
File diff suppressed because it is too large
Load Diff
11500
testdata/base/U15488.tests
vendored
11500
testdata/base/U15488.tests
vendored
File diff suppressed because it is too large
Load Diff
9007
testdata/shiftl/U1280.tests → testdata/base/U1600.tests
vendored
9007
testdata/shiftl/U1280.tests → testdata/base/U1600.tests
vendored
File diff suppressed because it is too large
Load Diff
11522
testdata/base/U16384.tests
vendored
11522
testdata/base/U16384.tests
vendored
File diff suppressed because it is too large
Load Diff
11496
testdata/base/U16448.tests
vendored
11496
testdata/base/U16448.tests
vendored
File diff suppressed because it is too large
Load Diff
11954
testdata/base/U16512.tests
vendored
11954
testdata/base/U16512.tests
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
11262
testdata/base/U1664.tests
vendored
11262
testdata/base/U1664.tests
vendored
File diff suppressed because it is too large
Load Diff
6006
testdata/base/U1728.tests
vendored
Normal file
6006
testdata/base/U1728.tests
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5834
testdata/base/U192.tests
vendored
5834
testdata/base/U192.tests
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user