Add examples from Alexander Semenov

A new Cryptol user! Alexander Semenov from the Russian Academy of
Sciences is the developer of the Transalg tool, which can also translate
cryptographic algorithms (written in imperative form) into SAT problems.
He recently started experimenting with Cryptol, and wrote up
implementations of several stream ciphers, included in this commit.
This commit is contained in:
Aaron Tomb 2016-02-18 15:08:17 -08:00
parent 8be10f62bf
commit 9809e176eb
3 changed files with 164 additions and 0 deletions

53
examples/contrib/A51.cry Normal file
View File

@ -0,0 +1,53 @@
/* Source:
Alexander Semenov
Institute for System Dynamics and Control Theory
Russian Academy of Sciences
*/
A51_stream : [19] -> [22] -> [23] -> [inf]
A51_stream R1 R2 R3 = R1s ^ R2s ^ R3s
where
(R1s, R1f) = lfsrki <| x^^19 + x^^18 + x^^17 + x^^14 + 1 |> R1c R1
(R2s, R2f) = lfsrki <| x^^22 + x^^21 + 1 |> R2c R2
(R3s, R3f) = lfsrki <| x^^23 + x^^22 + x^^21 + x^^8 + 1 |> R3c R3
majvs = [ majv (r1@8) (r2@10) (r3@10) | r1 <- R1f | r2 <- R2f | r3 <- R3f ]
R1c = [ r1@8 == m | r1 <- R1f | m <- majvs ]
R2c = [ r2@10 == m | r2 <- R2f | m <- majvs ]
R3c = [ r3@10 == m | r3 <- R3f | m <- majvs ]
type N = 128
A51 : ([19], [22], [23]) -> [N]Bit
A51(reg1, reg2, reg3) = keystream
where
keystream = take`{N} (A51_stream reg1 reg2 reg3)
lfsrki_step : {d} (fin d, d >=1) => [d+1] -> Bit -> [d] -> [d]
lfsrki_step poly cond fill = fill'
where
feedback_bit = if(poly@0) then prefix (^) (reverse([False]#fill) && poly)
else error "polynomial does not have high-bit set."
fill' = if cond then [feedback_bit]#(take fill) else fill
lfsrki : {d} (fin d, d >=1) => [d+1] -> [inf] -> [d] -> ([inf], [inf][d])
lfsrki poly conds init = (stream, fills)
where
lfsrki' = lfsrki_step poly
fills = [init] # [ lfsrki' c f | c <- conds | f <- fills]
stream = [ f!0 | f <- fills ]
prefix f xs = ys!0
where ys = [xs@0] # [ f y x | y <- ys | x <- tail xs ]
majv a b c = (a && b) || (a && c) || (b && c)
/***********************************************************************/
iv1 = 0b1010111011101011101
iv2 = 0b1010111011101010101110
iv3 = 0b10100000111100110011011
test_keystream = 0b00100100111010001110101110101100010100110111110101000101110000011101000111110101010000010011001111110101110001011010100000010001
property A51_correct = (A51(iv1, iv2, iv3)) == test_keystream
property A51_search x y z = A51(x,y,z) == test_keystream

View File

@ -0,0 +1,54 @@
/* Source:
Alexander Semenov
Institute for System Dynamics and Control Theory
Russian Academy of Sciences
*/
Bivium_stream : [93] -> [84] -> [inf]
Bivium_stream R1 R2 = stream
where
(stream, ra, rb) = shift_regs R1 R2
type N = 200
Bivium : ([93], [84]) -> [N]Bit
Bivium (reg1, reg2) = keystream
where
keystream = take`{N} (Bivium_stream reg1 reg2)
shift : {d} (fin d, d >=1) => [d] -> Bit -> [d]
shift fill bit = fills
where
fills = [bit]#(drop`{1} (fill >> 1))
shift_regs : {d,e} (fin d, fin e, d >=1, e >=1) => [d] -> [e] -> ([inf],[inf][d],[inf][e])
shift_regs r1 r2 = (stream, regA, regB)
where
s1 = [(f1 @ 65) ^ (f1 @ 92) | f1 <- regA]
s2 = [(f2 @ 68) ^ (f2 @ 83) | f2 <- regB]
stream = s1 ^ s2
t1 = [(f1 @ 65) ^ ((f1 @ 90) && (f1 @ 91)) ^ (f1 @ 92) ^ (f2 @ 77) |
f2 <- regB |
f1 <- regA ]
t2 = [(f2 @ 68) ^ ((f2 @ 81) && (f2 @ 82)) ^ (f2 @ 83) ^ (f1 @ 68) |
f1 <- regA |
f2 <- regB ]
regA = [r1] # [shift f b| f <- regA | b <- t2]
regB = [r2] # [shift f b| f <- regB | b <- t1]
/*************************************************************/
iv1 = 0b111110000000101010100100010001000000101010100001011111111111111100100100111111111011111111111
iv2 = 0b000000000000000000001000000000000000000001000000000000000000001000000000000000000001
test_keystream = 0b01000010000100000101110001100011111101110101110111111110100001111111100110101001000010101100100010000100001100011100000010001001100101101001011101110100000001011010001101000011001000110011111010100110
suffix = 0b000000001000000000000000000001
property Bivium_correct = (Bivium(iv1, iv2)) == test_keystream
property Bivium_search (x, y) = (Bivium(x, y)) == test_keystream
property Bivium_search_with_suffix (x, y) = (Bivium(x, y#suffix)) == test_keystream

View File

@ -0,0 +1,57 @@
/* Source:
Alexander Semenov
Institute for System Dynamics and Control Theory
Russian Academy of Sciences
*/
Trivium_stream : [93] -> [84] -> [111] -> [inf]
Trivium_stream R1 R2 R3 = stream
where
(stream, ra, rb, rc) = shift_regs R1 R2 R3
type N = 300
Trivium : ([93], [84], [111]) -> [N]Bit
Trivium (reg1, reg2, reg3) = keystream
where
keystream = take`{N} (Trivium_stream reg1 reg2 reg3)
shift : {d} (fin d, d >=1) => [d] -> Bit -> [d]
shift fill bit = fills
where
fills = [bit]#(drop`{1} (fill >> 1))
shift_regs : {d,e,f} (fin d, fin e, fin f, d >=1, e >=1, f>=1) => [d] -> [e] -> [f] -> ([inf],[inf][d],[inf][e],[inf][f])
shift_regs r1 r2 r3 = (stream, regA, regB, regC)
where
s1 = [(f1 @ 65) ^ (f1 @ 92) | f1 <- regA]
s2 = [(f2 @ 68) ^ (f2 @ 83) | f2 <- regB]
s3 = [(f3 @ 65) ^ (f3 @ 110) | f3 <- regC]
stream = s1 ^ s2 ^ s3
t1 = [(f1 @ 65) ^ ((f1 @ 90) && (f1 @ 91)) ^ (f1 @ 92) ^ (f2 @ 77) |
f2 <- regB |
f1 <- regA ]
t2 = [(f2 @ 68) ^ ((f2 @ 81) && (f2 @ 82)) ^ (f2 @ 83) ^ (f3 @ 86) |
f2 <- regB |
f3 <- regC ]
t3 = [(f3 @ 65) ^ ((f3 @ 108) && (f3 @ 109)) ^ (f3 @ 110) ^ (f1 @ 68)|
f1 <- regA |
f3 <- regC ]
regA = [r1] # [shift f b| f <- regA | b <- t3]
regB = [r2] # [shift f b| f <- regB | b <- t2]
regC = [r3] # [shift f b| f <- regC | b <- t1]
/*********************************************************/
iv1 = 0b111111111111111111101111111111111111111011111111111111111110111111111111111111101111111111111
iv2 = 0b000000000000000000001000000000000000000001000000000000000000001000000000000000000001
iv3 = 0b111111111111111110111111111111111111101111111111111111111011111111111111111110111111111111100000000000000000000
test_keystream = 0b011111110111101111110100001110000000000000100010000000000000000100111100101001010100001111110011101001000100000001110010010001100000101001010110001000110101111111001010010011011100011110111100101100000101110001111111110100000100001110110000110101001010100001110001111010000000000100010001000000100001
property Trivium_correct = (Trivium(iv1, iv2, iv3)) == test_keystream
property Trivium_search (x, y, z) = (Trivium(x, y, z)) == test_keystream