Remove some duplicate files from /examples that were also in cryptol-specs.

See #571.
This commit is contained in:
Brian Huffman 2019-03-01 18:34:23 -08:00
parent acafb2952d
commit 9584fdb54d
17 changed files with 0 additions and 3363 deletions

View File

@ -1,34 +0,0 @@
/*
* Copyright (c) 2014-2016 Galois, Inc.
* Distributed under the terms of the BSD3 license (see LICENSE file)
*/
fnv1a : {n} (fin n) => [n] -> [64]
fnv1a ws = fnv1a' (pad ws)
pad : {msgLen} (fin msgLen) => [msgLen] -> [msgLen /^ 8][8]
pad msg = split (msg # (zero:[msgLen %^ 8]))
fnv1a' : {chunks} (fin chunks) => [chunks][8] -> [64]
fnv1a' msg = Ss ! 0
where
Ss = [fnv1a_offset_basis] #
[ block s m
| s <- Ss
| m <- msg
]
block : {padLen} ( padLen == 64 - 8) => [64] -> [8] -> [64]
block state val = (state ^ ((zero : [padLen]) # val)) * fnv1a_prime
fnv1a_offset_basis : [64]
fnv1a_offset_basis = 14695981039346656037
fnv1a_prime : [64]
fnv1a_prime = 1099511628211
t1 = fnv1a [] == 0xcbf29ce484222325
t2 = fnv1a (join "a") == 0xaf63dc4c8601ec8c
t3 = fnv1a (join "foobar") == 0x85944171f73967e8
property testsPass = [t1, t2, t3] == ~zero

View File

@ -1,72 +0,0 @@
////////////////////////////////////////////////////////////////
// Copyright 2016 Galois, Inc. All Rights Reserved
//
// Authors:
// Aaron Tomb : atomb@galois.com
// Nathan Collins : conathan@galois.com
// Joey Dodds : jdodds@galois.com
//
// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.
// A copy of the License is located at
//
// http://aws.amazon.com/apache2.0
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.
//
////////////////////////////////////////////////////////////////
module HMAC where
import SHA256
//////// Functional version ////////
hmacSHA256 : {pwBytes, msgBytes}
(fin pwBytes, fin msgBytes
, 32 >= width msgBytes
, 64 >= width (8*pwBytes)
, 64 >= width (8 * (64 + msgBytes))
) => [pwBytes][8] -> [msgBytes][8] -> [256]
hmacSHA256 = hmac `{blockLength=64} SHA256 SHA256 SHA256
kinit : { pwBytes, blockLength, digest }
( fin pwBytes, fin blockLength, fin digest )
=> ([pwBytes][8] -> [8*digest])
-> [pwBytes][8]
-> [blockLength][8]
kinit hash key =
if `pwBytes > (`blockLength : [max (width pwBytes) (width blockLength)])
then take `{blockLength} (split (hash key) # (zero : [blockLength][8]))
else take `{blockLength} (key # (zero : [blockLength][8]))
// Due to limitations of the type system we must accept two
// separate arguments (both aledgedly the same) for two
// separate length inputs.
hmac : { msgBytes, pwBytes, digest, blockLength }
( fin pwBytes, fin digest, fin blockLength )
=> ([blockLength + msgBytes][8] -> [8*digest])
-> ([blockLength + digest][8] -> [8*digest])
-> ([pwBytes][8] -> [8*digest])
-> [pwBytes][8]
-> [msgBytes][8]
-> [digest*8]
hmac hash hash2 hash3 key message = hash2 (okey # internal)
where
ks : [blockLength][8]
ks = kinit hash3 key
okey = [k ^ 0x5C | k <- ks]
ikey = [k ^ 0x36 | k <- ks]
internal = split (hash (ikey # message))

View File

@ -1,271 +0,0 @@
// Copyright (c) 2001, 2014 Galois, Inc.
// Distributed under the terms of the BSD3 license (see LICENSE file)
//
// MD5 digest algorithm from RFC 1321
// https://www.ietf.org/rfc/rfc1321.txt
//
// Based on a previous Cryptol 1.* implementation
// Swap byte order from network to host order (long word)
ntohl : [32] -> [32]
ntohl w = join (reverse (groupBy`{8} w))
// Swap byte order from host to network order (long word)
htonl : [32] -> [32]
htonl w = join (reverse (groupBy`{8} w))
// Swap byte order from host to network order (long long word)
htonll : [64] -> [64]
htonll w = join (reverse (groupBy`{8} w))
// apply a function to every element of a sequence
map : {n, a, b} (a -> b) -> [n]a -> [n]b
map f xs = [ f x | x <- xs ]
// fold with left associativity
foldl : {n, a, b} (fin n) => a -> (a -> b -> a) -> [n]b -> a
foldl seed f xs = res ! 0
where res = [seed] # [ f a x | a <- res
| x <- xs
]
// Test driver. Given a sequence of bytes, calculate the MD5 sum.
test s = md5 (join s)
// Reference implementation of MD5 on exactly 16 bytes.
md5_ref : [16][8] -> [16][8]
md5_ref msg = map reverse (groupBy`{8} (md5`{p=319} (join (map reverse msg))))
md5_ref' : [128] -> [128]
md5_ref' msg = join (md5_ref (groupBy`{8} msg))
// The state of the MD5 algorithm after each 512 bit block
// consists of 4 32-bit words.
type MD5State = ([32],[32],[32],[32])
// Main MD5 algorithm.
//
// First, pad the message to a multiple of 512 bits.
// Next, initilize the MD5 state using the fixed values from the RFC.
// Then, process each message block in turn by computing
// the MD5 rounds using the message block. Add the result
// of the final round to the current MD5 state.
// Finally, return the current MD5 state after all blocks are processed,
// interpreting the 4 32-bit words as a single 128-bit sequence.
md5 : {a, b, p} (fin p, 512 * b == 65 + (a + p), 64 >= width a, 511 >= p) =>
[a] -> [128]
md5 msg = md5output finalState
where
finalState : MD5State
finalState = foldl initialMD5State processBlock blocks
blocks : [b][512]
blocks = groupBy`{512} (pad `{a,p} msg)
add : MD5State -> MD5State -> MD5State
add (a, b, c, d) (e, f, g, h) = (a + e, b + f, c + g, d + h)
processBlock : MD5State -> [512] -> MD5State
processBlock st blk = add st (computeRounds (decodeBlock blk) st)
// Initial seed for the digest rounds
//
// See RFC 1321, section 3.3
initialMD5State : MD5State
initialMD5State = (A, B, C, D)
where
f x = ntohl (join x)
A = f [ 0x01, 0x23, 0x45, 0x67 ]
B = f [ 0x89, 0xAB, 0xCD, 0xEF ]
C = f [ 0xFE, 0xDC, 0xBA, 0x98 ]
D = f [ 0x76, 0x54, 0x32, 0x10 ]
// Each MD5 message block 512 bits long, interpreted as a sequence of 16 32-bit words
// Each word is given as a sequence of 4 bytes, with LEAST significant byte first
// Each byte is given as a sequence of 8 bits, with MOST significant bit first
//
// The output of the algorithm is a sequence of 4 words, interpreted as above
//
// See RFC 1321, section 2
decodeBlock : [512] -> [16][32]
decodeBlock s = map ntohl (groupBy`{32} s)
// Interpret 4 32-bit words as a single 128-bit sequence
//
// See RFC 1321 section 3.5
md5output : MD5State -> [128]
md5output (a,b,c,d) = htonl a # htonl b # htonl c # htonl d
// Given an arbitrary byte sequence whose length can be described
// by a 64-bit number, pad the message so it is exactly a multiple of 512.
//
// This is done by adding a single 1 bit to the end of the message, and
// then adding enough zero bits to make the whole message 64 bits shorter
// than a multiple of 512. The size (in bits) of the original message is
// then appended to complete the padded message.
//
// See RFC 1321, sections 3.1 and 3.2
pad : {a, p} (fin p, 64 >= width a) => [a] -> [65 + (a + p)]
pad msg =
msg # [True] # zero # htonll sz
where
sz : [64]
sz = length msg
// Given a message block (interpreted as 16 32-bit words) and a current MD5 state
// (as 4 32-bit words) compute the values of all the rounds of the MD5 algorithm.
//
// In the main MD5 function, the final round will be used to compute the next MD5 state.
//
// See RFC 1321, section 3.4
computeRounds : [16][32] -> MD5State -> MD5State
computeRounds msg st = rounds (msg,st) @ 64
rounds : ([16][32], MD5State) -> [65]MD5State
rounds (msg, (a0, b0, c0, d0)) =
[ (a, b, c, d) | a <- as
| b <- bs
| c <- cs
| d <- ds
]
where
bs =
[b0] #
[box (i, a, b, c, d, m, t, s) | i <- [0 .. 63]
| a <- as
| b <- bs
| c <- cs
| d <- ds
| m <- join [m @@ p | m <- [msg, msg, msg, msg]
| p <- permutes
]
| t <- sineTbl
| s <- s_constants
]
cs = [c0] # bs
ds = [d0] # cs
as = [a0] # ds
// 'S' constants from the MD5 algorithm, used to indicated how many
// bits to rotate in the box function.
//
// See RFC 1321, section 3.4, and the appendix on page 10
s_constants : [64][6]
s_constants =
repeat4 [7, 12, 17, 22] #
repeat4 [5, 9, 14, 20] #
repeat4 [4, 11, 16, 23] #
repeat4 [6, 10, 15, 21]
where
repeat4 abcd = abcd # abcd # abcd # abcd
// This table of permutations indicates which word of the message block to
// use in a given MD5 round. Its structure is most evident via observing
// the indices of the message block in the order they are used in the MD5
// reference implementation.
//
// See the appendix of RFC 1321, starting on page 13.
permutes : [4][16][4]
permutes =
[ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
, [ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12]
, [ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2]
, [ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9]
]
// The main "box" operation. The first argument indicates
// the round number, which is used to select between the box
// operations, F, G, H, and I.
//
// See RFC 1321, section 3.4
box : ([6], [32], [32], [32], [32], [32], [32], [6]) -> [32]
box (i, a, b, c, d, m, t, s) =
b + (a + boxfunc (i, b, c, d) + m + t <<< s)
boxfunc : ([6],[32],[32],[32]) -> [32]
boxfunc (i, b, c, d) =
if i < 16 then F (b, c, d) else
if i < 32 then G (b, c, d) else
if i < 48 then H (b, c, d) else
I (b, c, d)
F : ([32], [32], [32]) -> [32]
F (x, y, z) = x && y || (~x) && z
G : ([32], [32], [32]) -> [32]
G (x, y, z) = x && z || y && ~z
H : ([32], [32], [32]) -> [32]
H (x, y, z) = x ^ y ^ z
I : ([32], [32], [32]) -> [32]
I (x, y, z) = y ^ (x || ~z)
// The table of values generated from the sin function, as described
// in RFC 1321, section 3.4. These values are transcribed from
// the appendix, starting on page 13.
sineTbl : [64][32]
sineTbl =
[0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, 0xF57C0FAF,
0x4787C62A, 0xA8304613, 0xFD469501, 0x698098D8, 0x8B44F7AF,
0xFFFF5BB1, 0x895CD7BE, 0x6B901122, 0xFD987193, 0xA679438E,
0x49B40821, 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA,
0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, 0x21E1CDE6,
0xC33707D6, 0xF4D50D87, 0x455A14ED, 0xA9E3E905, 0xFCEFA3F8,
0x676F02D9, 0x8D2A4C8A, 0xFFFA3942, 0x8771F681, 0x6D9D6122,
0xFDE5380C, 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70,
0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, 0xD9D4D039,
0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, 0xF4292244, 0x432AFF97,
0xAB9423A7, 0xFC93A039, 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D,
0x85845DD1, 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1,
0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391]
// The MD5 test suite from RFC 1321, appendix A.5
property r0 = test ""
== 0xd41d8cd98f00b204e9800998ecf8427e
property r1 = test "a"
== 0x0cc175b9c0f1b6a831c399e269772661
property r2 = test "abc"
== 0x900150983cd24fb0d6963f7d28e17f72
property r3 = test "message digest"
== 0xf96b697d7cb7938d525a2f31aaf161d0
property r4 = test "abcdefghijklmnopqrstuvwxyz"
== 0xc3fcd3d76192e4007dfb496cca67e13b
property r5 = test "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
== 0xd174ab98d277d9f5a5611c2c9f419d9f
property r6 = test "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
== 0x57edf4a22be3c955ac49da2e2107b67a
alltests = r0 /\ r1 /\ r2 /\ r3 /\ r4 /\ r5 /\ r6

View File

@ -1,88 +0,0 @@
/*
* Copyright (c) 2004, 2013-2016 Galois, Inc.
* Distributed under the terms of the BSD3 license (see LICENSE file)
*/
// Description of SHA1 at http://www.itl.nist.gov/fipspubs/fip180-4.htm
sha1 : {n} (width (8*n) <= 64) => [n][8] -> [160]
sha1 msg = sha1' pmsg
where
pmsg = pad(join(msg))
sha1' : {chunks} (fin chunks) => [chunks][512] -> [160]
sha1' pmsg = join (Hs!0)
where
Hs = [[0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0]] #
[ block(H, split(M))
| H <- Hs
| M <- pmsg
]
/*
As a summary, a "1" followed by m "0"s followed by a 64-
bit integer are appended to the end of the message to produce a
padded message of length 512 * n. The 64-bit integer is the length
of the original message. The padded message is then processed by the
SHA-1 as n 512-bit blocks.
*/
pad : {msgLen}
( fin msgLen
, 64 >= width msgLen // message width fits in a word
)
=> [msgLen] -> [(msgLen + 65) /^ 512][512]
pad msg = split (msg # [True] # (zero:[padLen]) # (`msgLen:[64]))
where type contentLen = msgLen + 65 // message + header
type padLen = (msgLen + 65) %^ 512
f : ([8], [32], [32], [32]) -> [32]
f (t, x, y, z) =
if (0 <= t) /\ (t <= 19) then (x && y) ^ (~x && z)
| (20 <= t) /\ (t <= 39) then x ^ y ^ z
| (40 <= t) /\ (t <= 59) then (x && y) ^ (x && z) ^ (y && z)
| (60 <= t) /\ (t <= 79) then x ^ y ^ z
else error "f: t out of range"
Ks : [80][32]
Ks = [ 0x5a827999 | t <- [0..19] ]
# [ 0x6ed9eba1 | t <- [20..39] ]
# [ 0x8f1bbcdc | t <- [40..59] ]
# [ 0xca62c1d6 | t <- [60..79] ]
block : ([5][32], [16][32]) -> [5][32]
block ([H0, H1, H2, H3, H4], M) =
[(H0+As@80), (H1+Bs@80), (H2+Cs@80), (H3+Ds@80), (H4+Es@80)]
where
Ws : [80][32]
Ws = M # [ (W3 ^ W8 ^ W14 ^ W16) <<< 1
| W16 <- drop`{16 - 16} Ws
| W14 <- drop`{16 - 14} Ws
| W8 <- drop`{16 - 8} Ws
| W3 <- drop`{16 - 3} Ws
| t <- [16..79]
]
As = [H0] # TEMP
Bs = [H1] # As
Cs = [H2] # [ B <<< 30 | B <- Bs ]
Ds = [H3] # Cs
Es = [H4] # Ds
TEMP : [80][32]
TEMP = [ (A <<< 5) + f(t, B, C, D) + E + W + K
| A <- As | B <- Bs | C <- Cs | D <- Ds | E <- Es
| W <- Ws | K <- Ks
| t <- [0..79]
]
t0 = sha1 "" == 0xda39a3ee5e6b4b0d3255bfef95601890afd80709
// Sample messages and their digests from FIPS180-1 appendix.
t1 = sha1 "abc" == 0xA9993E364706816ABA3E25717850C26C9CD0D89D
t2 = sha1 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ==
0x84983E441C3BD26EBAAE4AA1F95129E5E54670F1
t3 = sha1 [ 'a' | i <- [1..1000000] ] ==
0x34AA973CD4C4DAA4F61EEB2BDBAD27316534016F
property testsPass = [t0, t1, t2, t3] == ~zero

View File

@ -1,188 +0,0 @@
/*
* Copyright (c) 2013-2016 Galois, Inc.
* Distributed under the terms of the BSD3 license (see LICENSE file)
*
* @tmd - 24 April 2015 - took Ian's SHA512, converted to SHA256
* @ian - 15 August 2015 - he lies, probably ment 2014.
*
* This is a very simple implementation of SHA256, designed to be as clearly
* mathced to the specification in NIST's FIPS-PUB-180-4 as possible
*
* * The output correctly matches on all test vectors from
* http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf
*/
module SHA256 where
/*
* SHA256 Functions : Section 4.1.2
*/
Ch : [32] -> [32] -> [32] -> [32]
Ch x y z = (x && y) ^ (~x && z)
Maj : [32] -> [32] -> [32] -> [32]
Maj x y z = (x && y) ^ (x && z) ^ (y && z)
S0 : [32] -> [32]
S0 x = (x >>> 2) ^ (x >>> 13) ^ (x >>> 22)
S1 : [32] -> [32]
S1 x = (x >>> 6) ^ (x >>> 11) ^ (x >>> 25)
s0 : [32] -> [32]
s0 x = (x >>> 7) ^ (x >>> 18) ^ (x >> 3)
s1 : [32] -> [32]
s1 x = (x >>> 17) ^ (x >>> 19) ^ (x >> 10)
/*
* SHA256 Constants : Section 4.2.2
*/
K : [64][32]
K = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
]
/*
* Preprocessing (padding and parsing) for SHA256 : Section 5.1.1 and 5.2.1
*/
preprocess : {msgLen}
( fin msgLen
, 64 >= width msgLen // message width fits in a word
)
=> [msgLen] -> [(msgLen + 65) /^ 512][512]
preprocess msg = split (msg # [True] # (zero:[(msgLen + 65) %^ 512]) # (`msgLen:[64]))
/*
* SHA256 Initial Hash Value : Section 5.3.3
*/
H0 : [8][32]
H0 = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]
/*
* The SHA256 Hash computation : Section 6.2.2
*
* We have split the computation into a message scheduling function, corresponding
* to step 1 in the documents loop, and a compression function, corresponding to steps 2-4.
*/
SHA256MessageSchedule : [16][32] -> [64][32]
SHA256MessageSchedule M = W where
W = M # [ s1 (W@(j-2)) + (W@(j-7)) + s0 (W@(j-15)) + (W@(j-16)) | j <- [16 .. 63]:[_][8] ]
SHA256Compress : [8][32] -> [64][32] -> [8][32]
SHA256Compress H W = [as!0 + H@0, bs!0 + H@1, cs!0 + H@2, ds!0 + H@3, es!0 + H@4, fs!0 + H@5, gs!0 + H@6, hs!0 + H@7] where
T1 = [h + S1 e + Ch e f g + k + w | h <- hs | e <- es | f <- fs | g <- gs | k <- K | w <- W]
T2 = [S0 a + Maj a b c | a <- as | b <- bs | c <- cs]
hs = take `{65} ([H@7] # gs)
gs = take `{65} ([H@6] # fs)
fs = take `{65} ([H@5] # es)
es = take `{65} ([H@4] # [d + t1 | d <- ds | t1 <- T1])
ds = take `{65} ([H@3] # cs)
cs = take `{65} ([H@2] # bs)
bs = take `{65} ([H@1] # as)
as = take `{65} ([H@0] # [t1 + t2 | t1 <- T1 | t2 <- T2])
SHA256Block : [8][32] -> [16][32] -> [8][32]
SHA256Block H M = SHA256Compress H (SHA256MessageSchedule M)
//////// Functional/idiomatic top level ////////
/*
* The SHA256' function hashes a preprocessed sequence of blocks with the
* compression function. The SHA256 function hashes a sequence of bytes, and
* is more likely the function that will be similar to those seein in an
* implementation to be verified.
*/
SHA256' : {a} (fin a) => [a][16][32] -> [8][32]
SHA256' blocks = hash!0 where
hash = [H0] # [SHA256Block h b | h <- hash | b <- blocks]
SHA256 : {a} (fin a, 64 >= width (8*a)) => [a][8] -> [256]
SHA256 msg = join (SHA256' [ split x | x <- preprocess(join msg)])
property katsPass = ~zero == [test == kat | (test,kat) <- kats ]
kats = [ (SHA256 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
, 0x248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1)
, (SHA256 ""
,0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)
, (SHA256 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
, 0xcf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1)
// , ([0x61 | i <- [1..1000000] : [_][32]]
// , 0xcdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0)
]
//////// Imperative top level ////////
type SHA256State = { h : [8][32]
, block : [64][8]
, n : [16]
, sz : [64]
}
SHA256Init : SHA256State
SHA256Init = { h = H0
, block = zero
, n = 0
, sz = 0
}
SHA256Update1 : SHA256State -> [8] -> SHA256State
SHA256Update1 s b =
if s.n == 64
then { h = SHA256Block s.h (split (join s.block))
, block = [b] # zero
, n = 1
, sz = s.sz + 8
}
else { h = s.h
, block = update s.block s.n b
, n = s.n + 1
, sz = s.sz + 8
}
SHA256Update : {n} (fin n) => SHA256State -> [n][8] -> SHA256State
SHA256Update sinit bs = ss!0
where ss = [sinit] # [ SHA256Update1 s b | s <- ss | b <- bs ]
// Add padding and size and process the final block.
SHA256Final : SHA256State -> [256]
SHA256Final s = join (SHA256Block h b')
// Because the message is always made up of bytes, and the size is a
// fixed number of bytes, the 1 pad will always be at least a byte.
where s' = SHA256Update1 s 0x80
// Don't need to add zeros. They're already there. Just update
// the count of bytes in this block. After adding the 1 pad, there
// are two possible cases: the size will fit in the current block,
// or it won't.
(h, b) = if s'.n <= 56 then (s'.h, s'.block)
else (SHA256Block s'.h (split (join s'.block)), zero)
b' = split (join b || (zero # s.sz))
SHA256Imp : {a} (64 >= width (8*a)) => [a][8] -> [256]
SHA256Imp msg = SHA256Final (SHA256Update SHA256Init msg)
property katsPassImp = ~zero == [test == kat | (test,kat) <- katsImp ]
katsImp = [ (SHA256Imp "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 0x248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1), (SHA256Imp ""
, 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)
, (SHA256Imp "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
, 0xcf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1)
// , ([0x61 | i <- [1..1000000] : [_][32]]
// , 0xcdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0)
]
property imp_correct msg = SHA256 msg == SHA256Imp msg

File diff suppressed because it is too large Load Diff

View File

@ -1,182 +0,0 @@
/*
* Copyright (c) 2013-2016 Galois, Inc.
* Distributed under the terms of the BSD3 license (see LICENSE file)
*/
// see http://cr.yp.to/snuffle/spec.pdf
module Salsa20 where
quarterround : [4][32] -> [4][32]
quarterround [y0, y1, y2, y3] = [z0, z1, z2, z3]
where
z1 = y1 ^ ((y0 + y3) <<< 0x7)
z2 = y2 ^ ((z1 + y0) <<< 0x9)
z3 = y3 ^ ((z2 + z1) <<< 0xd)
z0 = y0 ^ ((z3 + z2) <<< 0x12)
property quarterround_passes_tests =
(quarterround [0x00000000, 0x00000000, 0x00000000, 0x00000000] == [0x00000000, 0x00000000, 0x00000000, 0x00000000]) /\
(quarterround [0x00000001, 0x00000000, 0x00000000, 0x00000000] == [0x08008145, 0x00000080, 0x00010200, 0x20500000]) /\
(quarterround [0x00000000, 0x00000001, 0x00000000, 0x00000000] == [0x88000100, 0x00000001, 0x00000200, 0x00402000]) /\
(quarterround [0x00000000, 0x00000000, 0x00000001, 0x00000000] == [0x80040000, 0x00000000, 0x00000001, 0x00002000]) /\
(quarterround [0x00000000, 0x00000000, 0x00000000, 0x00000001] == [0x00048044, 0x00000080, 0x00010000, 0x20100001]) /\
(quarterround [0xe7e8c006, 0xc4f9417d, 0x6479b4b2, 0x68c67137] == [0xe876d72b, 0x9361dfd5, 0xf1460244, 0x948541a3]) /\
(quarterround [0xd3917c5b, 0x55f1c407, 0x52a58a7a, 0x8f887a3b] == [0x3e2f308c, 0xd90a8f36, 0x6ab2a923, 0x2883524c])
rowround : [16][32] -> [16][32]
rowround [y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14, y15] =
[z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14, z15]
where
[ z0, z1, z2, z3] = quarterround [ y0, y1, y2, y3]
[ z5, z6, z7, z4] = quarterround [ y5, y6, y7, y4]
[z10, z11, z8, z9] = quarterround [y10, y11, y8, y9]
[z15, z12, z13, z14] = quarterround [y15, y12, y13, y14]
property rowround_passes_tests =
(rowround [0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0x00000000, 0x00000000, 0x00000000] ==
[0x08008145, 0x00000080, 0x00010200, 0x20500000,
0x20100001, 0x00048044, 0x00000080, 0x00010000,
0x00000001, 0x00002000, 0x80040000, 0x00000000,
0x00000001, 0x00000200, 0x00402000, 0x88000100]) /\
(rowround [0x08521bd6, 0x1fe88837, 0xbb2aa576, 0x3aa26365,
0xc54c6a5b, 0x2fc74c2f, 0x6dd39cc3, 0xda0a64f6,
0x90a2f23d, 0x067f95a6, 0x06b35f61, 0x41e4732e,
0xe859c100, 0xea4d84b7, 0x0f619bff, 0xbc6e965a] ==
[0xa890d39d, 0x65d71596, 0xe9487daa, 0xc8ca6a86,
0x949d2192, 0x764b7754, 0xe408d9b9, 0x7a41b4d1,
0x3402e183, 0x3c3af432, 0x50669f96, 0xd89ef0a8,
0x0040ede5, 0xb545fbce, 0xd257ed4f, 0x1818882d])
rowround_opt : [16][32] -> [16][32]
rowround_opt ys = join [ (quarterround (yi<<<i))>>>i | yi <- split ys | i <- [0 .. 3] ]
property rowround_opt_is_rowround ys = rowround ys == rowround_opt ys
columnround : [16][32] -> [16][32]
columnround [x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15] =
[y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14, y15]
where
[ y0, y4, y8, y12] = quarterround [ x0, x4, x8, x12]
[ y5, y9, y13, y1] = quarterround [ x5, x9, x13, x1]
[y10, y14, y2, y6] = quarterround [x10, x14, x2, x6]
[y15, y3, y7, y11] = quarterround [x15, x3, x7, x11]
property columnround_passes_tests =
(columnround [0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0x00000000, 0x00000000, 0x00000000] ==
[0x10090288, 0x00000000, 0x00000000, 0x00000000,
0x00000101, 0x00000000, 0x00000000, 0x00000000,
0x00020401, 0x00000000, 0x00000000, 0x00000000,
0x40a04001, 0x00000000, 0x00000000, 0x00000000]) /\
(columnround [0x08521bd6, 0x1fe88837, 0xbb2aa576, 0x3aa26365,
0xc54c6a5b, 0x2fc74c2f, 0x6dd39cc3, 0xda0a64f6,
0x90a2f23d, 0x067f95a6, 0x06b35f61, 0x41e4732e,
0xe859c100, 0xea4d84b7, 0x0f619bff, 0xbc6e965a] ==
[0x8c9d190a, 0xce8e4c90, 0x1ef8e9d3, 0x1326a71a,
0x90a20123, 0xead3c4f3, 0x63a091a0, 0xf0708d69,
0x789b010c, 0xd195a681, 0xeb7d5504, 0xa774135c,
0x481c2027, 0x53a8e4b5, 0x4c1f89c5, 0x3f78c9c8])
columnround_opt : [16][32] -> [16][32]
columnround_opt xs = join (transpose [ (quarterround (xi<<<i))>>>i | xi <- transpose(split xs) | i <- [0 .. 3] ])
columnround_opt_is_columnround xs = columnround xs == columnround_opt xs
property columnround_is_transpose_of_rowround ys =
rowround ys == join(transpose(split`{4}(columnround xs)))
where xs = join(transpose(split`{4} ys))
doubleround : [16][32] -> [16][32]
doubleround(xs) = rowround(columnround(xs))
property doubleround_passes_tests =
(doubleround [0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000] ==
[0x8186a22d, 0x0040a284, 0x82479210, 0x06929051,
0x08000090, 0x02402200, 0x00004000, 0x00800000,
0x00010200, 0x20400000, 0x08008104, 0x00000000,
0x20500000, 0xa0000040, 0x0008180a, 0x612a8020]) /\
(doubleround [0xde501066, 0x6f9eb8f7, 0xe4fbbd9b, 0x454e3f57,
0xb75540d3, 0x43e93a4c, 0x3a6f2aa0, 0x726d6b36,
0x9243f484, 0x9145d1e8, 0x4fa9d247, 0xdc8dee11,
0x054bf545, 0x254dd653, 0xd9421b6d, 0x67b276c1] ==
[0xccaaf672, 0x23d960f7, 0x9153e63a, 0xcd9a60d0,
0x50440492, 0xf07cad19, 0xae344aa0, 0xdf4cfdfc,
0xca531c29, 0x8e7943db, 0xac1680cd, 0xd503ca00,
0xa74b2ad6, 0xbc331c5c, 0x1dda24c7, 0xee928277])
littleendian : [4][8] -> [32]
littleendian b = join(reverse b)
property littleendian_passes_tests =
(littleendian [ 0, 0, 0, 0] == 0x00000000) /\
(littleendian [ 86, 75, 30, 9] == 0x091e4b56) /\
(littleendian [255, 255, 255, 250] == 0xfaffffff)
littleendian_inverse : [32] -> [4][8]
littleendian_inverse b = reverse(split b)
property littleendian_is_invertable b = littleendian_inverse(littleendian b) == b
Salsa20 : [64][8] -> [64][8]
Salsa20 xs = join ar
where
ar = [ littleendian_inverse words | words <- xw + zs@10 ]
xw = [ littleendian xi | xi <- split xs ]
zs = [xw] # [ doubleround zi | zi <- zs ]
property Salsa20_passes_tests =
(Salsa20 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ==
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) /\
(Salsa20 [211, 159, 13, 115, 76, 55, 82, 183, 3, 117, 222, 37, 191, 187, 234, 136,
49, 237, 179, 48, 1, 106, 178, 219, 175, 199, 166, 48, 86, 16, 179, 207,
31, 240, 32, 63, 15, 83, 93, 161, 116, 147, 48, 113, 238, 55, 204, 36,
79, 201, 235, 79, 3, 81, 156, 47, 203, 26, 244, 243, 88, 118, 104, 54] ==
[109, 42, 178, 168, 156, 240, 248, 238, 168, 196, 190, 203, 26, 110, 170, 154,
29, 29, 150, 26, 150, 30, 235, 249, 190, 163, 251, 48, 69, 144, 51, 57,
118, 40, 152, 157, 180, 57, 27, 94, 107, 42, 236, 35, 27, 111, 114, 114,
219, 236, 232, 135, 111, 155, 110, 18, 24, 232, 95, 158, 179, 19, 48, 202]) /\
(Salsa20 [ 88, 118, 104, 54, 79, 201, 235, 79, 3, 81, 156, 47, 203, 26, 244, 243,
191, 187, 234, 136, 211, 159, 13, 115, 76, 55, 82, 183, 3, 117, 222, 37,
86, 16, 179, 207, 49, 237, 179, 48, 1, 106, 178, 219, 175, 199, 166, 48,
238, 55, 204, 36, 31, 240, 32, 63, 15, 83, 93, 161, 116, 147, 48, 113] ==
[179, 19, 48, 202, 219, 236, 232, 135, 111, 155, 110, 18, 24, 232, 95, 158,
26, 110, 170, 154, 109, 42, 178, 168, 156, 240, 248, 238, 168, 196, 190, 203,
69, 144, 51, 57, 29, 29, 150, 26, 150, 30, 235, 249, 190, 163, 251, 48,
27, 111, 114, 114, 118, 40, 152, 157, 180, 57, 27, 94, 107, 42, 236, 35])
property Salsa20_has_no_collisions x1 x2 =
if(x1 != x2) then (doubleround x1) != (doubleround x2) else True
// Salsa 20 supports two key sizes, [16][8] and [32][8]
Salsa20_expansion : {a} (a >= 1, 2 >= a) => ([16*a][8], [16][8]) -> [64][8]
Salsa20_expansion(k, n) = z
where
[s0, s1, s2, s3] = split "expand 32-byte k" : [4][4][8]
[t0, t1, t2, t3] = split "expand 16-byte k" : [4][4][8]
x = if(`a == 2) then s0 # k0 # s1 # n # s2 # k1 # s3
else t0 # k0 # t1 # n # t2 # k0 # t3
z = Salsa20(x)
[k0, k1] = (split(k#zero)):[2][16][8]
Salsa20_encrypt : {a, l} (a >= 1, 2 >= a, l <= 2^^70) => ([16*a][8], [8][8], [l][8]) -> [l][8]
Salsa20_encrypt(k, v, m) = c
where
salsa = take (join [ Salsa20_expansion(k, v#(reverse (split i))) | i <- [0, 1 ... ] ])
c = m ^ salsa

View File

@ -1,208 +0,0 @@
module Threefish where
// This implementation is based on Skein version 1.3:
// http://www.skein-hash.info/sites/default/files/skein1.3.pdf
//////////////////////////////////////////////////////////////////////
// Section 3.2: Bit and Byte Order
// "To convert from a sequence of bytes to an integer, we use the
// least-significant-byte-first convention."
ToInt : {n} (fin n) => [n][8] -> [8 * n]
ToInt bytes = join (reverse bytes)
ToBytes : {n} (fin n) => [8 * n] -> [n][8]
ToBytes bits = reverse (split`{each = 8} bits)
BytesToWords : {n} (fin n) => [8 * n][8] -> [n][64]
BytesToWords bytes = [ ToInt bs | bs <- split`{each = 8} bytes ]
WordsToBytes : {n} (fin n) => [n][64] -> [8 * n][8]
WordsToBytes words = join [ ToBytes w | w <- words ]
//////////////////////////////////////////////////////////////////////
// Section 3.3: A Full Specification of Threefish
enc256 = encrypt`{Nr=72} R4 pi4
enc512 = encrypt`{Nr=72} R8 pi8
enc1024 = encrypt`{Nr=80} R16 pi16
encrypt :
{Nr, Nw} (fin Nr, fin Nw, Nw >= 3, Nr % 4 == 0, Nw % 2 == 0) =>
[8][Nw/2]Rot ->
([Nw][64] -> [Nw][64]) ->
[8 * Nw][8] -> [16][8] -> [8 * Nw][8] -> [8 * Nw][8]
encrypt R pi key tweak plaintext = WordsToBytes (encrypt'`{Nr=Nr} R pi K T P)
where
K = BytesToWords key
T = BytesToWords tweak
P = BytesToWords plaintext
// Encryption in terms of 64-bit words.
encrypt' :
{Nr, Nw} (fin Nr, fin Nw, Nw >= 3, Nr % 4 == 0, Nw % 2 == 0) =>
[8][Nw/2]Rot -> ([Nw][64] -> [Nw][64]) ->
[Nw][64] -> [2][64] -> [Nw][64] -> [Nw][64]
encrypt' R pi key tweak plaintext = last v + last ks
where
ks : [Nr/4 + 1][Nw][64]
ks = KeySchedule key tweak
// Add a subkey from the key schedule once every four rounds.
e : [Nr][Nw][64]
e = [ vd + kd
| vd <- v
| subkey <- take`{Nr/4} ks, kd <- [subkey, zero, zero, zero] ]
// Cycle over the eight lists of rotation amounts for the mixing function.
f : [Nr][Nw][64]
f = [ mixing Rd ed | Rd <- join (repeat`{inf} R) | ed <- e ]
// Permute the words every round.
v : [Nr+1][Nw][64]
v = [plaintext] # [ pi fd | fd <- f ]
// One round of mixing.
mixing : {w} (fin w) => [w]Rot -> [2 * w][64] -> [2 * w][64]
mixing Rd e = join [ MIX R x | R <- Rd | x <- split`{each=2} e ]
// Table 3: Values for the word permutation π(i).
pi4 : [4][64] -> [4][64]
pi4 xs = xs @@ [0, 3, 2, 1:[2]]
pi8 : [8][64] -> [8][64]
pi8 xs = xs @@ [2, 1, 4, 7, 6, 5, 0, 3:[3]]
pi16 : [16][64] -> [16][64]
pi16 xs = xs @@ [0, 9, 2, 13, 6, 11, 4, 15, 10, 7, 12, 3, 14, 5, 8, 1:[4]]
//////////////////////////////////////////////////////////////////////
// Section 3.3.1: MIX Functions
// Rotation amount for a 64-bit word
type Rot = [6]
MIX : Rot -> [2][64] -> [2][64]
MIX R [x0, x1] = [y0, y1]
where
y0 = x0 + x1
y1 = (x1 <<< R) ^ y0
// Table 4: Rotation constants
R4 : [8][2]Rot
R4 =
[[14, 16],
[52, 57],
[23, 40],
[ 5, 37],
[25, 33],
[46, 12],
[58, 22],
[32, 32]]
R8 : [8][4]Rot
R8 =
[[46, 36, 19, 37],
[33, 27, 14, 42],
[17, 49, 36, 39],
[44, 9, 54, 56],
[39, 30, 34, 24],
[13, 50, 10, 17],
[25, 29, 39, 43],
[ 8, 35, 56, 22]]
R16 : [8][8]Rot
R16 =
[[24, 13, 8, 47, 8, 17, 22, 37],
[38, 19, 10, 55, 49, 18, 23, 52],
[33, 4, 51, 13, 34, 41, 59, 17],
[ 5, 20, 48, 41, 47, 28, 16, 25],
[41, 9, 37, 31, 12, 47, 44, 30],
[16, 34, 56, 51, 4, 53, 42, 41],
[31, 44, 47, 46, 19, 42, 44, 25],
[ 9, 48, 35, 52, 23, 31, 37, 20]]
//////////////////////////////////////////////////////////////////////
// Section 3.3.2: The Key Schedule
// "The key schedule turns the key and tweak into a sequence of Nr/4+1
// subkeys, each of which consists of Nw words."
KeySchedule :
{Nw, r} (fin Nw, fin r, Nw >= 3) =>
[Nw][64] -> [2][64] -> [r][Nw][64]
KeySchedule k [t0,t1] = take`{r} [ subkey s | s <- [0...] ]
where
k' = k # [foldl (^) C240 k]
t' = [t0, t1, t0 ^ t1]
subkey : [64] -> [Nw][64]
subkey s = take`{Nw} (k' <<< s) + tweak s
tweak : [64] -> [Nw][64]
tweak s = zero # take`{2} (t' <<< s) # [s]
C240 : [64]
C240 = 0x1BD11BDAA9FC1A22
//////////////////////////////////////////////////////////////////////
// Test Vectors
// https://sites.google.com/site/bartoszmalkowski/threefish
property test256a =
enc256 zero zero zero ==
split 0x84da2a1f8beaee947066ae3e3103f1ad536db1f4a1192495116b9f3ce6133fd8
property test256b =
enc256
(split 0x101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f)
(split 0x000102030405060708090a0b0c0d0e0f)
(split 0xFFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0)
==
split 0xe0d091ff0eea8fdfc98192e62ed80ad59d865d08588df476657056b5955e97df
property test512a =
enc512 zero zero zero ==
split 0xb1a2bbc6ef6025bc40eb3822161f36e375d1bb0aee3186fbd19e47c5d479947b #
split 0x7bc2f8586e35f0cff7e7f03084b0b7b1f1ab3961a580a3e97eb41ea14a6d7bbe
property test512b =
enc512
(split 0x101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f #
split 0x303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f)
(split 0x000102030405060708090a0b0c0d0e0f)
(split 0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0 #
split 0xdfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0)
==
split 0xe304439626d45a2cb401cad8d636249a6338330eb06d45dd8b36b90e97254779 #
split 0x272a0a8d99463504784420ea18c9a725af11dffea10162348927673d5c1caf3d
property test1024a =
enc1024 zero zero zero ==
split 0xf05c3d0a3d05b304f785ddc7d1e036015c8aa76e2f217b06c6e1544c0bc1a90d #
split 0xf0accb9473c24e0fd54fea68057f43329cb454761d6df5cf7b2e9b3614fbd5a2 #
split 0x0b2e4760b40603540d82eabc5482c171c832afbe68406bc39500367a592943fa #
split 0x9a5b4a43286ca3c4cf46104b443143d560a4b230488311df4feef7e1dfe8391e
property test1024b =
enc1024
(split 0x101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f #
split 0x303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f #
split 0x505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f #
split 0x707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f)
(split 0x000102030405060708090a0b0c0d0e0f)
(split 0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0 #
split 0xdfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0 #
split 0xbfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a0 #
split 0x9f9e9d9c9b9a999897969594939291908f8e8d8c8b8a89888786858483828180)
==
split 0xa6654ddbd73cc3b05dd777105aa849bce49372eaaffc5568d254771bab85531c #
split 0x94f780e7ffaae430d5d8af8c70eebbe1760f3b42b737a89cb363490d670314bd #
split 0x8aa41ee63c2e1f45fbd477922f8360b388d6125ea6c7af0ad7056d01796e90c8 #
split 0x3313f4150a5716b30ed5f569288ae974ce2b4347926fce57de44512177dd7cde

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2013-2016 Galois, Inc.
* Distributed under the terms of the BSD3 license (see LICENSE file)
*/
module TripleDES where
import DES
blockEncrypt : ([64],[64],[64],[64]) -> [64]
blockEncrypt (k1,k2,k3,data) = result where
ex = DES.encrypt k1 data
dx = DES.decrypt k2 ex
result = DES.encrypt k3 dx
// Test vectors from NIST 800-67
Key1, Key2, Key3 : [64]
Key1 = 0x0123456789ABCDEF
Key2 = 0x23456789ABCDEF01
Key3 = 0x456789ABCDEF0123
P1, P2, P3 : [64]
PlainText = "The qufck brown fox jump"
// Yes, that's the correct phrase.. (see the 7th letter of the phrase).
// It's supposed to be "the quick..." but they made a mistake in transcribing
// the ASCII into hex.
[P1, P2, P3] = split`{3} (join PlainText)
// B.1
C1, C2, C3 : [64]
C1 = 0xA826FD8CE53B855F
C2 = 0xCCE21C8112256FE6
C3 = 0x68D5C05DD9B6B900
test_B1_1 = blockEncrypt (Key1, Key2, Key3, P1) == C1
test_B1_2 = blockEncrypt (Key1, Key2, Key3, P2) == C2
test_B1_3 = blockEncrypt (Key1, Key2, Key3, P3) == C3
property passesTests = [test_B1_1, test_B1_2, test_B1_3] == ~zero

View File

@ -1,308 +0,0 @@
// Copyright (c) 2011-2016 Galois, Inc.
// An implementation of ZUC, Version 1.5
// Version info: If the following variable is set to True, then we implement
// Version 1.5 of ZUC. Otherwise, version 1.4 is implemented. There are
// precisely two points in the implementation where the difference matters,
// search for occurrences of version1_5 to spot them.
// Note that the ZUC test vectors below will not work for version 1.4, as the
// old test vectors are no longer published.
version1_5 : Bit
version1_5 = True
// addition in GF(2^31-1) over a list of terms
add : {a} (fin a) => [a][31] -> [31]
add xs =
sums ! 0
where
sums =
[0] #
[plus (s, x) | s <- sums
| x <- xs]
// the binary addition specified in the note at the end of section 3.2
plus : ([31], [31]) -> [31]
plus (a, b) =
if sab @ 0 then sab' + 1 else sab'
where
sab : [32]
sab = ((zero : [1]) # a) + ((zero : [1]) # b)
sab' : [31]
sab' = drop sab
// The ZUC LFSR is 16 31-bit words
type LFSR = [16][31]
// Section 3.2
LFSRWithInitializationMode : ([31], LFSR) -> LFSR
LFSRWithInitializationMode (u, ss) =
ss @@ [1 .. 15] # [s16]
where
v = add [s <<< c | s <- ss @@ [15, 13, 10, 4, 0, 0]
| c <- [15, 17, 21, 20, 8, 0]]
vu = if version1_5 then add [v, u] else v ^ u
s16 = if vu == 0 then `0x7FFFFFFF else vu
// Section 3.2
LFSRWithWorkMode : LFSR -> LFSR
LFSRWithWorkMode ss =
ss @@ [1 .. 15] # [s16]
where
v = add [s <<< c | s <- ss @@ [15, 13, 10, 4, 0, 0]
| c <- [15, 17, 21, 20, 8, 0]]
s16 = if v == 0 then `0x7FFFFFFF else v
// Section 3.3
BitReorganization : LFSR -> [4][32]
BitReorganization ss =
[ hi s15 # lo s14
, lo s11 # hi s9
, lo s7 # hi s5
, lo s2 # hi s0]
where
lo : [31] -> [16]
hi : [31] -> [16]
lo x = x @@ [15 .. 30]
hi x = x @@ [0 .. 15]
[s0, s2, s5, s7, s9, s11, s14, s15] = ss @@ [0, 2, 5, 7, 9, 11, 14, 15]
// Section 3.4
F : ([3][32], [2][32]) -> ([32], [2][32])
F ([X0, X1, X2], [R1, R2]) =
(W, [R1', R2'])
where
W = (X0 ^ R1) + R2
W1 = R1 + X1
W2 = R2 ^ X2
[W1H, W1L] = split W1
[W2H, W2L] = split W2
R1' = S (L1 (W1L # W2H))
R2' = S (L2 (W2L # W1H))
// Section 3.4.1
S : [32] -> [32]
S X =
Y0 # Y1 # Y2 # Y3
where
[X0, X1, X2, X3] = split X
[Y0, Y1, Y2, Y3] = [S0 X0, S1 X1, S2 X2, S3 X3]
// Example 8
property example8 = S(0x12345678) == 0xF9C05A4E
S0 : [8] -> [8]
S1 : [8] -> [8]
S2 : [8] -> [8]
S3 : [8] -> [8]
S0 x = S0Table @ x
S1 x = S1Table @ x
S2 = S0
S3 = S1
// Table 3.1
S0Table : [256][8]
S0Table =
[0x3E, 0x72, 0x5B, 0x47, 0xCA, 0xE0, 0x00, 0x33, 0x04, 0xD1, 0x54,
0x98, 0x09, 0xB9, 0x6D, 0xCB, 0x7B, 0x1B, 0xF9, 0x32, 0xAF, 0x9D,
0x6A, 0xA5, 0xB8, 0x2D, 0xFC, 0x1D, 0x08, 0x53, 0x03, 0x90, 0x4D,
0x4E, 0x84, 0x99, 0xE4, 0xCE, 0xD9, 0x91, 0xDD, 0xB6, 0x85, 0x48,
0x8B, 0x29, 0x6E, 0xAC, 0xCD, 0xC1, 0xF8, 0x1E, 0x73, 0x43, 0x69,
0xC6, 0xB5, 0xBD, 0xFD, 0x39, 0x63, 0x20, 0xD4, 0x38, 0x76, 0x7D,
0xB2, 0xA7, 0xCF, 0xED, 0x57, 0xC5, 0xF3, 0x2C, 0xBB, 0x14, 0x21,
0x06, 0x55, 0x9B, 0xE3, 0xEF, 0x5E, 0x31, 0x4F, 0x7F, 0x5A, 0xA4,
0x0D, 0x82, 0x51, 0x49, 0x5F, 0xBA, 0x58, 0x1C, 0x4A, 0x16, 0xD5,
0x17, 0xA8, 0x92, 0x24, 0x1F, 0x8C, 0xFF, 0xD8, 0xAE, 0x2E, 0x01,
0xD3, 0xAD, 0x3B, 0x4B, 0xDA, 0x46, 0xEB, 0xC9, 0xDE, 0x9A, 0x8F,
0x87, 0xD7, 0x3A, 0x80, 0x6F, 0x2F, 0xC8, 0xB1, 0xB4, 0x37, 0xF7,
0x0A, 0x22, 0x13, 0x28, 0x7C, 0xCC, 0x3C, 0x89, 0xC7, 0xC3, 0x96,
0x56, 0x07, 0xBF, 0x7E, 0xF0, 0x0B, 0x2B, 0x97, 0x52, 0x35, 0x41,
0x79, 0x61, 0xA6, 0x4C, 0x10, 0xFE, 0xBC, 0x26, 0x95, 0x88, 0x8A,
0xB0, 0xA3, 0xFB, 0xC0, 0x18, 0x94, 0xF2, 0xE1, 0xE5, 0xE9, 0x5D,
0xD0, 0xDC, 0x11, 0x66, 0x64, 0x5C, 0xEC, 0x59, 0x42, 0x75, 0x12,
0xF5, 0x74, 0x9C, 0xAA, 0x23, 0x0E, 0x86, 0xAB, 0xBE, 0x2A, 0x02,
0xE7, 0x67, 0xE6, 0x44, 0xA2, 0x6C, 0xC2, 0x93, 0x9F, 0xF1, 0xF6,
0xFA, 0x36, 0xD2, 0x50, 0x68, 0x9E, 0x62, 0x71, 0x15, 0x3D, 0xD6,
0x40, 0xC4, 0xE2, 0x0F, 0x8E, 0x83, 0x77, 0x6B, 0x25, 0x05, 0x3F,
0x0C, 0x30, 0xEA, 0x70, 0xB7, 0xA1, 0xE8, 0xA9, 0x65, 0x8D, 0x27,
0x1A, 0xDB, 0x81, 0xB3, 0xA0, 0xF4, 0x45, 0x7A, 0x19, 0xDF, 0xEE,
0x78, 0x34, 0x60]
// Table 3.2
S1Table : [256][8]
S1Table =
[0x55, 0xC2, 0x63, 0x71, 0x3B, 0xC8, 0x47, 0x86, 0x9F, 0x3C, 0xDA,
0x5B, 0x29, 0xAA, 0xFD, 0x77, 0x8C, 0xC5, 0x94, 0x0C, 0xA6, 0x1A,
0x13, 0x00, 0xE3, 0xA8, 0x16, 0x72, 0x40, 0xF9, 0xF8, 0x42, 0x44,
0x26, 0x68, 0x96, 0x81, 0xD9, 0x45, 0x3E, 0x10, 0x76, 0xC6, 0xA7,
0x8B, 0x39, 0x43, 0xE1, 0x3A, 0xB5, 0x56, 0x2A, 0xC0, 0x6D, 0xB3,
0x05, 0x22, 0x66, 0xBF, 0xDC, 0x0B, 0xFA, 0x62, 0x48, 0xDD, 0x20,
0x11, 0x06, 0x36, 0xC9, 0xC1, 0xCF, 0xF6, 0x27, 0x52, 0xBB, 0x69,
0xF5, 0xD4, 0x87, 0x7F, 0x84, 0x4C, 0xD2, 0x9C, 0x57, 0xA4, 0xBC,
0x4F, 0x9A, 0xDF, 0xFE, 0xD6, 0x8D, 0x7A, 0xEB, 0x2B, 0x53, 0xD8,
0x5C, 0xA1, 0x14, 0x17, 0xFB, 0x23, 0xD5, 0x7D, 0x30, 0x67, 0x73,
0x08, 0x09, 0xEE, 0xB7, 0x70, 0x3F, 0x61, 0xB2, 0x19, 0x8E, 0x4E,
0xE5, 0x4B, 0x93, 0x8F, 0x5D, 0xDB, 0xA9, 0xAD, 0xF1, 0xAE, 0x2E,
0xCB, 0x0D, 0xFC, 0xF4, 0x2D, 0x46, 0x6E, 0x1D, 0x97, 0xE8, 0xD1,
0xE9, 0x4D, 0x37, 0xA5, 0x75, 0x5E, 0x83, 0x9E, 0xAB, 0x82, 0x9D,
0xB9, 0x1C, 0xE0, 0xCD, 0x49, 0x89, 0x01, 0xB6, 0xBD, 0x58, 0x24,
0xA2, 0x5F, 0x38, 0x78, 0x99, 0x15, 0x90, 0x50, 0xB8, 0x95, 0xE4,
0xD0, 0x91, 0xC7, 0xCE, 0xED, 0x0F, 0xB4, 0x6F, 0xA0, 0xCC, 0xF0,
0x02, 0x4A, 0x79, 0xC3, 0xDE, 0xA3, 0xEF, 0xEA, 0x51, 0xE6, 0x6B,
0x18, 0xEC, 0x1B, 0x2C, 0x80, 0xF7, 0x74, 0xE7, 0xFF, 0x21, 0x5A,
0x6A, 0x54, 0x1E, 0x41, 0x31, 0x92, 0x35, 0xC4, 0x33, 0x07, 0x0A,
0xBA, 0x7E, 0x0E, 0x34, 0x88, 0xB1, 0x98, 0x7C, 0xF3, 0x3D, 0x60,
0x6C, 0x7B, 0xCA, 0xD3, 0x1F, 0x32, 0x65, 0x04, 0x28, 0x64, 0xBE,
0x85, 0x9B, 0x2F, 0x59, 0x8A, 0xD7, 0xB0, 0x25, 0xAC, 0xAF, 0x12,
0x03, 0xE2, 0xF2]
// Section 3.4.2
L1 : [32] -> [32]
L1 X = X ^ X <<< 2 ^ X <<< 10 ^ X <<< 18 ^ X <<< 24
// Section 3.4.2
L2 : [32] -> [32]
L2 X = X ^ X <<< 8 ^ X <<< 14 ^ X <<< 22 ^ X <<< 30
// Section 3.5
LoadKey : ([128], [128]) -> LFSR
LoadKey (key, iv) =
[k # d # i | k <- ks
| i <- is
| d <- ds]
where
ks : [16][8]
ks = split key
is : [16][8]
is = split iv
ds : [16][15]
ds =
[ 0b100010011010111, 0b010011010111100
, 0b110001001101011, 0b001001101011110
, 0b101011110001001, 0b011010111100010
, 0b111000100110101, 0b000100110101111
, 0b100110101111000, 0b010111100010011
, 0b110101111000100, 0b001101011110001
, 0b101111000100110, 0b011110001001101
, 0b111100010011010, 0b100011110101100
]
type ZUC = (LFSR, [32], [32])
// Return an infinite sequence of ZUC states by applying the initialization step
// repeatedly. This is a generalization of section 3.6.1
InitializeZUC : ([128], [128]) -> [inf]ZUC
InitializeZUC (key, iv) =
outs
where
initLFSR = LoadKey (key, iv)
outs = [(initLFSR, 0, 0)] # [step out | out <- outs]
step (lfsr, R1, R2) =
(LFSRWithInitializationMode (drop (w >> 1), lfsr), R1', R2')
where
[X0, X1, X2, X3] = BitReorganization lfsr
(w', [R1', R2']) = F ([X0, X1, X2], [R1, R2])
w = if version1_5 then w' else w' ^ X3
// Section 3.6.2
WorkingStage : ZUC -> ZUC
WorkingStage (lfsr, R1, R2) =
(lfsr', R1', R2')
where
[X0, X1, X2, _] = BitReorganization lfsr
(_, [R1', R2']) = F ([X0, X1, X2], [R1, R2])
lfsr' = LFSRWithWorkMode lfsr
// Section 3.6.2
ProductionStage : ZUC -> ([32], ZUC)
ProductionStage (lfsr, R1, R2) =
(w ^ X3, (lfsr', R1', R2'))
where
[X0, X1, X2, X3] = BitReorganization lfsr
(w, [R1', R2']) = F ([X0, X1, X2], [R1, R2])
lfsr' = LFSRWithWorkMode lfsr
// ZUC API
ZUC : [128] -> [128] -> [inf][32]
ZUC key iv =
tail [w | (w, _) <- zucs]
where
initZuc = WorkingStage (InitializeZUC (key, iv) @ 32)
zucs = [(zero, initZuc)] # [ProductionStage zuc | (_, zuc) <- zucs]
// Test vectors
property ZUC_TestVectors =
t1 /\ t2 /\ t3 /\ t4
where
t1 = take (ZUC zero zero ) == [0x27BEDE74, 0x018082DA]
t2 = take (ZUC (~zero) (~zero)) == [0x0657CFA0, 0x7096398B]
t3 = take (ZUC (join [ 0x3D, 0x4C, 0x4B, 0xE9, 0x6A, 0x82, 0xFD, 0xAE
, 0xB5, 0x8F, 0x64, 0x1D, 0xB1, 0x7B, 0x45, 0x5B
])
(join [ 0x84, 0x31, 0x9A, 0xA8, 0xDE, 0x69, 0x15, 0xCA
, 0x1F, 0x6B, 0xDA, 0x6B, 0xFB, 0xD8, 0xC7, 0x66
])) == [0x14F1C272, 0x3279C419]
t4 = take ks # [ks @ 1999] == [0xED4400E7, 0x0633E5C5, 0x7A574CDB]
where
ks = ZUC (join [ 0x4D, 0x32, 0x0B, 0xFA, 0xD4, 0xC2, 0x85, 0xBF
, 0xD6, 0xB8, 0xBD, 0x00, 0xF3, 0x9D, 0x8B, 0x41
])
(join [ 0x52, 0x95, 0x9D, 0xAB, 0xA0, 0xBF, 0x17, 0x6E
, 0xCE, 0x2D, 0xC3, 0x15, 0x04, 0x9E, 0xB5, 0x74
])
// 3.3-3.6 of the implementor's test data document lists "LFSR-state at the
// beginning", which is immediately after running LoadKey.
property LoadKey_TestVectors =
[ LoadKey(k, iv) == lfsr0
| k <- ks
| iv <- ivs
| lfsr0 <- lfsr0s
] == ~0
where
ks = [ 0
, ~0
, 0x3d4c4be96a82fdaeb58f641db17b455b
, 0x4d320bfad4c285bfd6b8bd00f39d8b41
]
ivs = [ 0
, ~0
, 0x84319aa8de6915ca1f6bda6bfbd8c766
, 0x52959daba0bf176ece2dc315049eb574
]
lfsr0s = [ [ `0x0044d700, `0x0026bc00, `0x00626b00, `0x00135e00
, `0x00578900, `0x0035e200, `0x00713500, `0x0009af00
, `0x004d7800, `0x002f1300, `0x006bc400, `0x001af100
, `0x005e2600, `0x003c4d00, `0x00789a00, `0x0047ac00
]
, [ `0x7fc4d7ff, `0x7fa6bcff, `0x7fe26bff, `0x7f935eff
, `0x7fd789ff, `0x7fb5e2ff, `0x7ff135ff, `0x7f89afff
, `0x7fcd78ff, `0x7faf13ff, `0x7febc4ff, `0x7f9af1ff
, `0x7fde26ff, `0x7fbc4dff, `0x7ff89aff, `0x7fc7acff
]
, [ `0x1ec4d784, `0x2626bc31, `0x25e26b9a, `0x74935ea8
, `0x355789de, `0x4135e269, `0x7ef13515, `0x5709afca
, `0x5acd781f, `0x47af136b, `0x326bc4da, `0x0e9af16b
, `0x58de26fb, `0x3dbc4dd8, `0x22f89ac7, `0x2dc7ac66
]
, [ `0x26c4d752, `0x1926bc95, `0x05e26b9d, `0x7d135eab
, `0x6a5789a0, `0x6135e2bf, `0x42f13517, `0x5f89af6e
, `0x6b4d78ce, `0x5c2f132d, `0x5eebc4c3, `0x001af115
, `0x79de2604, `0x4ebc4d9e, `0x45f89ab5, `0x20c7ac74
]
]
// Collision attack on ZUC. Only version1.5 is resistant to it. Thus, the
// following theorem holds only when version1_5 is set to True.
//
// NB. We only compare the first output of the InitializeZUC sequence, as it
// cuts down on the problem size and is sufficient to ensure the iv's will be
// the same. That is, if this theorem fails, then so would the final iv's used
// by ZUC.
//
// Use a solver other than CVC4; Z3 and Boolector do it quickly.
property ZUC_isResistantToCollisionAttack k iv1 iv2 =
if iv1 != iv2
then InitializeZUC (k, iv1) @ 1 != InitializeZUC (k, iv2) @ 1
else True

View File

@ -1,75 +0,0 @@
/* 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]
Bivium_alt : ([93], [84]) -> [N]Bit
Bivium_alt (r1, r2) = take`{N} (s1 ^ s2)
where
a_65 = drop`{27} a_92
a_68 = drop`{24} a_92
a_90 = drop`{2} a_92
a_91 = drop`{1} a_92
a_92 = reverse r1 # t2
b_68 = drop`{15} b_83
b_77 = drop`{6} b_83
b_81 = drop`{2} b_83
b_82 = drop`{1} b_83
b_83 = reverse r2 # t1
s1 = a_65 ^ a_92
s2 = b_68 ^ b_83
t1 = s1 ^ (a_90 && a_91) ^ b_77
t2 = s2 ^ (b_81 && b_82) ^ a_68
/*************************************************************/
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
property Bivium_alt_equivalent r = Bivium_alt r == Bivium r

View File

@ -1,181 +0,0 @@
/*
* Copyright (c) 2013 David Lazar <lazard@galois.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Specification of the Keccak (SHA-3) hash function
// Author: David Lazar
SHA_3_224 M = take`{224} (Keccak `{r = 1152, c = 448} (M # 0b01))
SHA_3_256 M = take`{256} (Keccak `{r = 1088, c = 512} (M # 0b01))
SHA_3_384 M = take`{384} (Keccak `{r = 832, c = 768} (M # 0b01))
SHA_3_512 M = take`{512} (Keccak `{r = 576, c = 1024} (M # 0b01))
SHAKE128 M = Keccak`{r = 1344, c = 256} (M # 0b1111)
SHAKE256 M = Keccak`{r = 1088, c = 512} (M # 0b1111)
Keccak : {r, c, m}
( fin r, fin c, fin m
, r >= 1
, (r + c) % 25 == 0
, 64 >= (r + c) / 25
) => [m] -> [inf]
Keccak M = squeeze `{r = r} (absorb `{w = (r + c) / 25} Ps)
where Ps = pad `{r = r} M
squeeze : {r, w} (fin r, fin w, 64 >= w, r >= 0, 25 * w >= r) => [5][5][w] -> [inf]
squeeze A = take`{r} (flatten A) # squeeze`{r = r} (Keccak_f A)
absorb : {r, w, n} (fin r, fin w, fin n, 64 >= w, 25 * w >= r) => [n][r] -> [5][5][w]
absorb Ps = as ! 0
where
as = [zero] # [ Keccak_f `{w = w} (s ^ (unflatten p)) | s <- as | p <- Ps ]
pad : {r, m}
( fin r, fin m
, r >= 1
) => [m] -> [(m + 2) /^ r][r]
pad M = split (M # [True] # zero # [True])
Keccak_f : {w} (fin w, 64 >= w) => [5][5][w] -> [5][5][w]
Keccak_f A0 = rounds ! 0
where
rounds = [A0] # [ Round RC A | RC <- RCs`{w = w} | A <- rounds ]
Round : {w} (fin w) => [5][5][w] -> [5][5][w] -> [5][5][w]
Round RC A = ι RC (χ (π (ρ (θ A))))
θ : {w} (fin w) => [5][5][w] -> [5][5][w]
θ A = A'
where
C = [ xor a | a <- A ]
D = [ C @ x ^ (C @ y <<< 1)
| (x:[8]) <- [4,0,1,2,3]
| (y:[8]) <- [1,2,3,4,0]
]
A' = [ [ a ^ (D @ x) | a <- A @ x ] | (x:[8]) <- [0 .. 4] ]
ρ : {w} (fin w) => [5][5][w] -> [5][5][w]
ρ A = groupBy`{5} [ a <<< r | a <- join A | (r:[8]) <- R ]
where R = [00, 36, 03, 41, 18,
01, 44, 10, 45, 02,
62, 06, 43, 15, 61,
28, 55, 25, 21, 56,
27, 20, 39, 08, 14]
π : {w} (fin w) => [5][5][w] -> [5][5][w]
π A = groupBy`{5} [ A @ ((x + 3*y) % 5) @ x
| (x:[8]) <- [0..4], (y:[8]) <- [0..4]
]
χ : {w} (fin w) => [5][5][w] -> [5][5][w]
χ A = groupBy`{5} [ (A @ x @ y) ^ (~ A @ ((x + 1) % 5) @ y
&& A @ ((x + 2) % 5) @ y)
| (x:[8]) <- [0..4], (y:[8]) <- [0..4]
]
ι : {w} (fin w) => [5][5][w] -> [5][5][w] -> [5][5][w]
ι RC A = A ^ RC
RCs : {w, n} (fin w, fin n, 24 >= n, n == 12 + 2 * (lg2 w)) => [n][5][5][w]
RCs = take`{n} [ [[take`{w} RC] # zero] # zero | RC <- RCs64 ]
RCs64 : [24][64]
RCs64 = join (transpose [
[0x0000000000000001, 0x000000008000808B],
[0x0000000000008082, 0x800000000000008B],
[0x800000000000808A, 0x8000000000008089],
[0x8000000080008000, 0x8000000000008003],
[0x000000000000808B, 0x8000000000008002],
[0x0000000080000001, 0x8000000000000080],
[0x8000000080008081, 0x000000000000800A],
[0x8000000000008009, 0x800000008000000A],
[0x000000000000008A, 0x8000000080008081],
[0x0000000000000088, 0x8000000000008080],
[0x0000000080008009, 0x0000000080000001],
[0x000000008000000A, 0x8000000080008008]
])
unflatten : {r, w} (fin w, 25*w >= r) => [r] -> [5][5][w]
unflatten p = transpose (groupBy`{5} (reverse (groupBy`{w} (reverse (p # zero)))))
flatten : {w} (fin w) => [5][5][w] -> [5 * 5 * w]
flatten A = reverse (join (reverse (join (transpose A))))
xor : {a, b} (fin a) => [a][b] -> [b]
xor xs = xors ! 0
where xors = [zero] # [ x ^ z | x <- xs | z <- xors ]
property RC_correct i j =
(i:[8]) < 24 ==> (j:[8]) < 7 ==> RCs64@i!(2^^j - 1) == lfsr@(j + 7*i)
lfsr : [inf]
lfsr = [ p!0 | p <- ps ]
where
/* powers of x modulo m */
ps = [0x01] # [ pmod (pmult p 0b10) m | p <- ps ]
m = <| x^^8 + x^^6 + x^^5 + x^^4 + 1 |>
/* See https://keccak.team/files/Keccak-reference-3.0.pdf, Section 1.2 */
property unflatten_correct x y z p =
x < 5 ==> y < 5 ==> z < (64:[12]) ==>
p@((5*y + x)*64 + z) == unflatten`{1600,64} p @ x @ y ! z
property flatten_correct s =
unflatten`{1600,64} (flatten`{64} s) == s
/** Splits a list of bits into bytes, using little-endian bit order. **/
toBytes : {n} (fin n) => [8*n] -> [n][8]
toBytes s = reverse (split (reverse s))
/** Joins a list of bytes into a list of bits, using little-endian bit order. **/
fromBytes : {n} (fin n) => [n][8] -> [8*n]
fromBytes bs = reverse (join (reverse bs))
/*
Test vectors from
https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values#aHashing
*/
property t1 = join (toBytes (SHA_3_224 [])) ==
0x6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7
property t2 = join (toBytes (SHA_3_256 [])) ==
0xa7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a
property t3 = join (toBytes (SHA_3_384 [])) ==
0x0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004
property t4 = join (toBytes (SHA_3_512 [])) ==
0xa69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26
property u1 = join (toBytes (SHA_3_224 0b11001)) ==
0xffbad5da96bad71789330206dc6768ecaeb1b32dca6b3301489674ab
property u2 = join (toBytes (SHA_3_256 0b11001)) ==
0x7b0047cf5a456882363cbf0fb05322cf65f4b7059a46365e830132e3b5d957af
property u3 = join (toBytes (SHA_3_384 0b11001)) ==
0x737c9b491885e9bf7428e792741a7bf8dca9653471c3e148473f2c236b6a0a6455eb1dce9f779b4b6b237fef171b1c64
property u4 = join (toBytes (SHA_3_512 0b11001)) ==
0xa13e01494114c09800622a70288c432121ce70039d753cadd2e006e4d961cb27544c1481e5814bdceb53be6733d5e099795e5e81918addb058e22a9f24883f37
msg1600 : [1600]
msg1600 = join [ 0b11000101 | _ <- zero : [200] ]
property v1 = join (toBytes (SHA_3_224 msg1600)) ==
0x9376816aba503f72f96ce7eb65ac095deee3be4bf9bbc2a1cb7e11e0
property w1 = join (toBytes (SHA_3_224 (msg1600 # 0b11000))) ==
0x22d2f7bb0b173fd8c19686f9173166e3ee62738047d7eadd69efb228

View File

@ -1,146 +0,0 @@
/*
* Copyright (c) 2013-2016 Galois, Inc.
* Distributed under the terms of the BSD3 license (see LICENSE file)
*/
/* Cryptol specification of the Simon block cipher
* Author: David Lazar
*/
///////////////////////////////////////////////////////////////////////
// parameters
///////////////////////////////////////////////////////////////////////
module simon where
Simon32_64 = encrypt `{n=16,m=4,T=32,j=0}
Simon48_72 = encrypt `{n=24,m=3,T=36,j=0}
Simon48_96 = encrypt `{n=24,m=4,T=36,j=1}
Simon64_96 = encrypt `{n=32,m=3,T=42,j=2}
Simon64_128 = encrypt `{n=32,m=4,T=44,j=3}
Simon96_96 = encrypt `{n=48,m=2,T=52,j=2}
Simon96_144 = encrypt `{n=48,m=3,T=54,j=3}
Simon128_128 = encrypt `{n=64,m=2,T=68,j=2}
Simon128_192 = encrypt `{n=64,m=3,T=69,j=3}
Simon128_256 = encrypt `{n=64,m=4,T=72,j=4}
Simon32_64' = decrypt `{n=16,m=4,T=32,j=0}
Simon48_72' = decrypt `{n=24,m=3,T=36,j=0}
Simon48_96' = decrypt `{n=24,m=4,T=36,j=1}
Simon64_96' = decrypt `{n=32,m=3,T=42,j=2}
Simon64_128' = decrypt `{n=32,m=4,T=44,j=3}
Simon96_96' = decrypt `{n=48,m=2,T=52,j=2}
Simon96_144' = decrypt `{n=48,m=3,T=54,j=3}
Simon128_128' = decrypt `{n=64,m=2,T=68,j=2}
Simon128_192' = decrypt `{n=64,m=3,T=69,j=3}
Simon128_256' = decrypt `{n=64,m=4,T=72,j=4}
// check only a few of them for now
property correctSimon32_64 k b = Simon32_64' k (Simon32_64 k b) == b
property correctSimon64_96 k b = Simon64_96' k (Simon64_96 k b) == b
property correctSimon96_144 k b = Simon96_144' k (Simon96_144 k b) == b
property correctSimon128_128 k b = Simon128_128' k (Simon128_128 k b) == b
property correctSimon128_256 k b = Simon128_256' k (Simon128_256 k b) == b
property uniqueExpandSimon32_64 k1 k2 = (k1 == k2) || (expandKey `{n=16,m=4,T=32,j=0} k1 != expandKey `{n=16,m=4,T=32,j=0} k2)
property uniqueExpandSimon48_72 k1 k2 = (k1 == k2) || (expandKey `{n=24,m=3,T=36,j=0} k1 != expandKey `{n=24,m=3,T=36,j=0} k2)
property uniqueExpandSimon48_96 k1 k2 = (k1 == k2) || (expandKey `{n=24,m=4,T=36,j=1} k1 != expandKey `{n=24,m=4,T=36,j=1} k2)
property uniqueExpandSimon64_96 k1 k2 = (k1 == k2) || (expandKey `{n=32,m=3,T=42,j=2} k1 != expandKey `{n=32,m=3,T=42,j=2} k2)
property uniqueExpandSimon64_128 k1 k2 = (k1 == k2) || (expandKey `{n=32,m=4,T=44,j=3} k1 != expandKey `{n=32,m=4,T=44,j=3} k2)
property uniqueExpandSimon96_96 k1 k2 = (k1 == k2) || (expandKey `{n=48,m=2,T=52,j=2} k1 != expandKey `{n=48,m=2,T=52,j=2} k2)
property uniqueExpandSimon96_144 k1 k2 = (k1 == k2) || (expandKey `{n=48,m=3,T=54,j=3} k1 != expandKey `{n=48,m=3,T=54,j=3} k2)
property uniqueExpandSimon128_128 k1 k2 = (k1 == k2) || (expandKey `{n=64,m=2,T=68,j=2} k1 != expandKey `{n=64,m=2,T=68,j=2} k2)
property uniqueExpandSimon128_192 k1 k2 = (k1 == k2) || (expandKey `{n=64,m=3,T=69,j=3} k1 != expandKey `{n=64,m=3,T=69,j=3} k2)
property uniqueExpandSimon128_256 k1 k2 = (k1 == k2) || (expandKey `{n=64,m=4,T=72,j=4} k1 != expandKey `{n=64,m=4,T=72,j=4} k2)
// A weak key theorem would look something like:
// :prove exists (\k1 -> exists (\k2 -> forall (\x -> Simon32_64 k1 (Simon32_64 k2 x) != x)))
///////////////////////////////////////////////////////////////////////
// round function
///////////////////////////////////////////////////////////////////////
R k (x, y) = (y ^ f x ^ k, x)
// inverse
R' k (x, y) = (y, x ^ f y ^ k)
f x = ((x <<< 1) && (x <<< 8)) ^ (x <<< 2)
///////////////////////////////////////////////////////////////////////
// encryption / decryption
///////////////////////////////////////////////////////////////////////
encrypt : {n, m, T, j}
( fin n, fin m, fin T, fin j
, n >= 2, 4 >= m, T >= 4, T-1 >= m
) => [m][n] -> ([n], [n]) -> ([n], [n])
encrypt k0 b0 = bs ! 0
where
bs = [b0] # [ R k b | b <- bs | k <- ks ]
ks = expandKey `{n=n,m=m,T=T,j=j} (reverse k0)
decrypt : {n, m, T, j}
( fin n, fin m, fin T, fin j
, n >= 2, 4 >= m, T >= 4, T-1 >= m
) => [m][n] -> ([n], [n]) -> ([n], [n])
decrypt k0 b0 = bs ! 0
where
bs = [b0] # [ R' k b | b <- bs | k <- reverse ks ]
ks = expandKey `{n=n,m=m,T=T,j=j} (reverse k0)
///////////////////////////////////////////////////////////////////////
// key expansion
///////////////////////////////////////////////////////////////////////
expandKey : {n, m, T, j}
( fin n, fin m, fin T, fin j
, n >= 2, 4 >= m, T >= 4, T-1 >= m
) => [m][n] -> [T][n]
expandKey k0 = k
where
k = k0 # [ r where
o = k @ (i - 1) >>> 3
p = if `m == 4 then o ^ k @ (i - 3) else o
q = p ^ p >>> 1
r = ~ k @ (i - `m) ^ q ^ z ^ 3
z = Z @ `j @ ((i - `m) % 62)
| i <- [m .. T - 1]
]
// TODO specify how Z is constructed
Z = [[1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0,
0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1,
0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0],
[1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0,
0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1,
0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0],
[1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1],
[1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0,
0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1],
[1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1,
0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1]]
///////////////////////////////////////////////////////////////////////
// tests
///////////////////////////////////////////////////////////////////////
tests = [t00, t01,t02,t03,t04,t05,t06,t07,t08,t09]
property testsPass = tests == ~zero
t00 = Simon32_64 [0x1918, 0x1110, 0x0908, 0x0100] (0x6565, 0x6877) == (0xc69b, 0xe9bb)
t01 = Simon48_72 [0x121110, 0x0a0908, 0x020100] (0x612067, 0x6e696c) == (0xdae5ac, 0x292cac)
t02 = Simon48_96 [0x1a1918, 0x121110, 0x0a0908, 0x020100] (0x726963, 0x20646e) == (0x6e06a5, 0xacf156)
t03 = Simon64_96 [0x13121110, 0x0b0a0908, 0x03020100] (0x6f722067, 0x6e696c63) == (0x5ca2e27f, 0x111a8fc8)
t04 = Simon64_128 [0x1b1a1918, 0x13121110, 0x0b0a0908, 0x03020100] (0x656b696c, 0x20646e75) == (0x44c8fc20, 0xb9dfa07a)
t05 = Simon96_96 [0x0d0c0b0a0908, 0x050403020100] (0x2072616c6c69, 0x702065687420) == (0x602807a462b4, 0x69063d8ff082)
t06 = Simon96_144 [0x151413121110, 0x0d0c0b0a0908, 0x050403020100] (0x746168742074, 0x73756420666f) == (0xecad1c6c451e, 0x3f59c5db1ae9)
t07 = Simon128_128 [0x0f0e0d0c0b0a0908, 0x0706050403020100] (0x6373656420737265, 0x6c6c657661727420) == (0x49681b1e1e54fe3f, 0x65aa832af84e0bbc)
t08 = Simon128_192 [0x1716151413121110, 0x0f0e0d0c0b0a0908, 0x0706050403020100] (0x206572656874206e, 0x6568772065626972) == (0xc4ac61effcdc0d4f, 0x6c9c8d6e2597b85b)
t09 = Simon128_256 [0x1f1e1d1c1b1a1918, 0x1716151413121110, 0x0f0e0d0c0b0a0908, 0x0706050403020100] (0x74206e69206d6f6f, 0x6d69732061207369) == (0x8d2b5579afc8a3a0, 0x3bf72a87efe7b868)

View File

@ -1,121 +0,0 @@
/*
* Copyright (c) 2013-2016 Galois, Inc.
* Distributed under the terms of the BSD3 license (see LICENSE file)
*/
/* Cryptol specification of the Speck block cipher
* Author: David Lazar
*/
///////////////////////////////////////////////////////////////////////
// parameters
///////////////////////////////////////////////////////////////////////
Speck32_64 = encrypt`{n = 16, m = 4, T = 22}
Speck48_72 = encrypt`{n = 24, m = 3, T = 22}
Speck48_96 = encrypt`{n = 24, m = 4, T = 23}
Speck64_96 = encrypt`{n = 32, m = 3, T = 26}
Speck64_128 = encrypt`{n = 32, m = 4, T = 27}
Speck96_96 = encrypt`{n = 48, m = 2, T = 28}
Speck96_144 = encrypt`{n = 48, m = 3, T = 29}
Speck128_128 = encrypt`{n = 64, m = 2, T = 32}
Speck128_192 = encrypt`{n = 64, m = 3, T = 33}
Speck128_256 = encrypt`{n = 64, m = 4, T = 34}
Speck32_64' = decrypt`{n = 16, m = 4, T = 22}
Speck48_72' = decrypt`{n = 24, m = 3, T = 22}
Speck48_96' = decrypt`{n = 24, m = 4, T = 23}
Speck64_96' = decrypt`{n = 32, m = 3, T = 26}
Speck64_128' = decrypt`{n = 32, m = 4, T = 27}
Speck96_96' = decrypt`{n = 48, m = 2, T = 28}
Speck96_144' = decrypt`{n = 48, m = 3, T = 29}
Speck128_128' = decrypt`{n = 64, m = 2, T = 32}
Speck128_192' = decrypt`{n = 64, m = 3, T = 33}
Speck128_256' = decrypt`{n = 64, m = 4, T = 34}
// check only a few of them for now
property correctSpeck32_64 (k, b) = Speck32_64' k (Speck32_64 k b) == b
property correctSpeck64_96 (k, b) = Speck64_96' k (Speck64_96 k b) == b
property correctSpeck96_144 (k, b) = Speck96_144' k (Speck96_144 k b) == b
property correctSpeck128_128 (k, b) = Speck128_128' k (Speck128_128 k b) == b
property correctSpeck128_256 (k, b) = Speck128_256' k (Speck128_256 k b) == b
///////////////////////////////////////////////////////////////////////
// round function
///////////////////////////////////////////////////////////////////////
R : {n} (fin n) => [n] -> ([n], [n]) -> ([n], [n])
R k (x, y) = f2 (f1 k (x, y))
R' : {n} (fin n) => [n] -> ([n], [n]) -> ([n], [n])
R' k (x, y) = ((x ^ k) - z <<< (if `n == 16 then 7 else 8), z)
where z = (x ^ y) >>> (if `n == 16 then 2 else 3)
f1 : {n} (fin n) => [n] -> ([n], [n]) -> ([n], [n])
f1 k (x, y) = (y, (x >>> (if `n == 16 then 7 else 8)) + y ^ k)
f2 : {n} (fin n) => ([n], [n]) -> ([n], [n])
f2 (x, y) = (y, x <<< (if `n == 16 then 2 else 3) ^ y)
///////////////////////////////////////////////////////////////////////
// encryption / decryption
///////////////////////////////////////////////////////////////////////
encrypt : {n, m, T}
( fin n, fin m, fin T
, m >= 2, T >= 2, n >= 2
, n >= width (T-2)
) => [m][n] -> ([n], [n]) -> ([n], [n])
encrypt k0 b0 = bs ! 0
where
bs = [b0] # [R k b | b <- bs | k <- ks]
ks = expandKey`{n = n, m = m, T = T} (reverse k0)
decrypt : {n, m, T}
( fin n, fin m, fin T
, m >= 2, T >= 2, n >= 2
, n >= width (T-2)
) => [m][n] -> ([n], [n]) -> ([n], [n])
decrypt k0 b0 = bs ! 0
where
bs = [b0] # [R' k b | b <- bs | k <- reverse ks]
ks = expandKey`{n = n, m = m, T = T} (reverse k0)
///////////////////////////////////////////////////////////////////////
// key expansion
///////////////////////////////////////////////////////////////////////
expandKey : {n, m, T}
( fin n, fin m, fin T
, m >= 2, n >= 2, T >= 2
, n >= width (T-2)
) => [m][n] -> [T][n]
expandKey K = ks
where
ls = drop`{1} K # [snd (f1 i (l, k)) | l <- ls | k <- ks | i <- [0 .. T - 2]]
ks = take`{1} K # [snd (f2 (k, l)) | l <- drop`{m - 1} ls | k <- ks]
snd (x, y) = y
///////////////////////////////////////////////////////////////////////
// tests
///////////////////////////////////////////////////////////////////////
property testsPass = tests == ~zero
tests = [t01, t02, t03, t04, t05, t06, t07, t08, t09]
t00 = Speck32_64 [0x1918, 0x1110, 0x0908, 0x0100] (0x6574, 0x694C) == (0xA868, 0x42F2)
t01 = Speck48_72 [0x121110, 0x0A0908, 0x020100] (0x20796C, 0x6C6172) == (0xC049A5, 0x385ADC)
t02 = Speck48_96 [0x1A1918, 0x121110, 0x0A0908, 0x020100] (0x6D2073, 0x696874) == (0x735E10, 0xB6445D)
t03 = Speck64_96 [0x13121110, 0x0B0A0908, 0x03020100] (0x74614620, 0x736E6165) == (0x9F7952EC, 0x4175946C)
t04 = Speck64_128 [0x1B1A1918, 0x13121110, 0x0B0A0908, 0x03020100] (0x3B726574, 0x7475432D) == (0x8C6FA548, 0x454E028B)
t05 = Speck96_96 [0x0D0C0B0A0908, 0x050403020100] (0x65776F68202C, 0x656761737520) == (0x9E4D09AB7178, 0x62BDDE8F79AA)
t06 = Speck96_144 [0x151413121110, 0x0D0C0B0A0908, 0x050403020100] (0x656D6974206E, 0x69202C726576) == (0x2BF31072228A, 0x7AE440252EE6)
t07 = Speck128_128 [0x0F0E0D0C0B0A0908, 0x0706050403020100] (0x6C61766975716520, 0x7469206564616D20) == (0xA65D985179783265, 0x7860FEDF5C570D18)
t08 = Speck128_192 [0x1716151413121110, 0x0F0E0D0C0B0A0908, 0x0706050403020100] (0x7261482066656968, 0x43206F7420746E65) == (0x1BE4CF3A13135566, 0xF9BC185DE03C1886)
t09 = Speck128_256 [0x1F1E1D1C1B1A1918, 0x1716151413121110, 0x0F0E0D0C0B0A0908, 0x0706050403020100] (0x65736F6874206E49, 0x202E72656E6F6F70) == (0x4109010405C0F53E, 0x4EEEB48D9C188F43)

View File

@ -1,87 +0,0 @@
/* 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 <- t1]
regC = [r3] # [shift f b| f <- regC | b <- t2]
Trivium_alt : ([93], [84], [111]) -> [N]Bit
Trivium_alt (r1, r2, r3) = take`{N} (s1 ^ s2 ^ s3)
where
a_65 = drop`{27} a_92
a_68 = drop`{24} a_92
a_90 = drop`{2} a_92
a_91 = drop`{1} a_92
a_92 = reverse r1 # t3
b_68 = drop`{15} b_83
b_77 = drop`{6} b_83
b_81 = drop`{2} b_83
b_82 = drop`{1} b_83
b_83 = reverse r2 # t1
c_65 = drop`{45} c_110
c_86 = drop`{24} c_110
c_108 = drop`{2} c_110
c_109 = drop`{1} c_110
c_110 = reverse r3 # t2
s1 = a_65 ^ a_92
s2 = b_68 ^ b_83
s3 = c_65 ^ c_110
t1 = s1 ^ (a_90 && a_91) ^ b_77
t2 = s2 ^ (b_81 && b_82) ^ c_86
t3 = s3 ^ (c_108 && c_109) ^ a_68
/*********************************************************/
iv1 = 0b111111111111111111101111111111111111111011111111111111111110111111111111111111101111111111111
iv2 = 0b000000000000000000001000000000000000000001000000000000000000001000000000000000000001
iv3 = 0b111111111111111110111111111111111111101111111111111111111011111111111111111110111111111111100000000000000000000
test_keystream = 0b011111110111101111110100001110000000000000100010000000000000000100011000101100001110001011011010101010000100101110001111100011000110000101001011001111011101110110111010011011010110001000111101101111101100101001000111010001010011111110011100100011101010011110101001001000011100001111111100000001110001
property Trivium_correct = (Trivium(iv1, iv2, iv3)) == test_keystream
property Trivium_search (x, y, z) = (Trivium(x, y, z)) == test_keystream
property Trivium_alt_correct = (Trivium_alt(iv1, iv2, iv3)) == test_keystream
property Trivium_alt_equivalent x = take`{200}(Trivium_alt x) == take (Trivium x)

View File

@ -6,18 +6,8 @@
:l Cipher.cry
:l DES.cry
:l DEStest.cry
:l FNV-a1.cry
:l HMAC.cry
:l Karatsuba.cry
:l MD5.cry
:l SHA1.cry
:l SHA256.cry
:l SIV-rfc5297.md
:l Salsa20.cry
:l Test.cry
:l Threefish.cry
:l TripleDES.cry
:l ZUC.cry
:l append.cry
:l builtin_lifting.cry
:l builtins.cry
@ -36,12 +26,7 @@
:l contrib/EvenMansour.cry
:l contrib/MISTY1.cry
:l contrib/RC4.cry
:l contrib/bivium.cry
:l contrib/keccak.cry
:l contrib/mkrand.cry
:l contrib/simon.cry
:l contrib/speck.cry
:l contrib/trivium.cry
:l funstuff/Coins.cry
:l funstuff/FoxChickenCorn.cry
:l funstuff/NQueens.cry

View File

@ -26,39 +26,11 @@ Loading module DES
Loading module Test
Loading module DEStest
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module SHA256
Loading module HMAC
Loading module Cryptol
Loading module Karatsuba
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module Main
[warning] at ./SHA1.cry:36:16--36:26 Unused name: contentLen
Loading module Cryptol
Loading module SHA256
Loading module Cryptol
Loading module AES
Loading module SIV
[warning] at ./SIV-rfc5297.md:494:8--494:9 Unused name: k
[warning] at ./SIV-rfc5297.md:494:7--494:64:
Assuming k to have a numeric type
Loading module Cryptol
Loading module Salsa20
Loading module Cryptol
Loading module Cipher
Loading module Test
Loading module Cryptol
Loading module Threefish
Loading module Cryptol
Loading module Cipher
Loading module DES
Loading module TripleDES
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module Main
@ -97,18 +69,8 @@ Loading module MISTY1
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module MKRAND
Loading module Cryptol
Loading module simon
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module Main
Loading module Cryptol
Loading module FoxChickenCorn