2014-04-18 02:34:25 +04:00
|
|
|
/*
|
2016-01-19 22:31:37 +03:00
|
|
|
* Copyright (c) 2013-2016 Galois, Inc.
|
2014-04-18 02:34:25 +04:00
|
|
|
* Distributed under the terms of the BSD3 license (see LICENSE file)
|
|
|
|
*/
|
|
|
|
|
|
|
|
module Cryptol where
|
|
|
|
|
2015-06-06 01:47:12 +03:00
|
|
|
/**
|
|
|
|
* The value corresponding to a numeric type.
|
|
|
|
*/
|
|
|
|
primitive demote : {val, bits} (fin val, fin bits, bits >= width val) => [bits]
|
|
|
|
|
2016-08-13 03:12:34 +03:00
|
|
|
infixr 5 ==>
|
|
|
|
infixr 10 \/
|
|
|
|
infixr 15 /\
|
|
|
|
infixr 20 ||
|
|
|
|
infixr 25 &&
|
2015-06-10 21:55:54 +03:00
|
|
|
infix 30 ==, ===, !=, !==
|
|
|
|
infix 40 >, >=, <, <=
|
|
|
|
infixl 50 ^
|
|
|
|
infixr 60 #
|
|
|
|
infixl 70 <<, <<<, >>, >>>
|
|
|
|
infixl 80 +, -
|
2016-08-09 18:25:26 +03:00
|
|
|
infixl 90 *, /, %
|
2015-06-10 21:55:54 +03:00
|
|
|
infixr 95 ^^
|
|
|
|
infixl 100 @, @@, !, !!
|
2015-06-05 04:35:12 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Add two values.
|
|
|
|
* * For words, addition uses modulo arithmetic.
|
|
|
|
* * Structured values are added element-wise.
|
|
|
|
*/
|
2015-06-04 08:29:36 +03:00
|
|
|
primitive (+) : {a} (Arith a) => a -> a -> a
|
|
|
|
|
2015-06-06 01:47:12 +03:00
|
|
|
/**
|
|
|
|
* For words, subtraction uses modulo arithmetic.
|
|
|
|
* Structured values are subtracted element-wise. Defined as:
|
|
|
|
* a - b = a + negate b
|
|
|
|
* See also: `negate'.
|
|
|
|
*/
|
|
|
|
primitive (-) : {a} (Arith a) => a -> a -> a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For words, multiplies two words, modulus 2^^a.
|
|
|
|
* Structured values are multiplied element-wise.
|
|
|
|
*/
|
|
|
|
primitive (*) : {a} (Arith a) => a -> a -> a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For words, divides two words, modulus 2^^a.
|
|
|
|
* Structured values are divided element-wise.
|
|
|
|
*/
|
|
|
|
primitive (/) : {a} (Arith a) => a -> a -> a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For words, takes the modulus of two words, modulus 2^^a.
|
|
|
|
* Over structured values, operates element-wise.
|
|
|
|
* Be careful, as this will often give unexpected results due to interaction of
|
|
|
|
* the two moduli.
|
|
|
|
*/
|
|
|
|
primitive (%) : {a} (Arith a) => a -> a -> a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For words, takes the exponent of two words, modulus 2^^a.
|
|
|
|
* Over structured values, operates element-wise.
|
|
|
|
* Be careful, due to its fast-growing nature, exponentiation is prone to
|
|
|
|
* interacting poorly with defaulting.
|
|
|
|
*/
|
|
|
|
primitive (^^) : {a} (Arith a) => a -> a -> a
|
|
|
|
|
2015-06-09 01:58:46 +03:00
|
|
|
/**
|
2015-06-06 01:47:12 +03:00
|
|
|
* Log base two.
|
2016-02-19 21:08:20 +03:00
|
|
|
*
|
2015-06-06 01:47:12 +03:00
|
|
|
* For words, computes the ceiling of log, base 2, of a number.
|
|
|
|
* Over structured values, operates element-wise.
|
|
|
|
*/
|
2015-06-09 01:58:46 +03:00
|
|
|
primitive lg2 : {a} (Arith a) => a -> a
|
2015-06-06 01:47:12 +03:00
|
|
|
|
|
|
|
|
2014-04-18 02:34:25 +04:00
|
|
|
type Bool = Bit
|
2015-06-06 01:47:12 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The constant True. Corresponds to the bit value 1.
|
|
|
|
*/
|
2015-06-05 04:35:12 +03:00
|
|
|
primitive True : Bit
|
2015-06-06 01:47:12 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The constant False. Corresponds to the bit value 0.
|
|
|
|
*/
|
2015-06-05 04:35:12 +03:00
|
|
|
primitive False : Bit
|
|
|
|
|
2015-06-09 01:58:46 +03:00
|
|
|
/**
|
|
|
|
* Returns the twos complement of its argument.
|
|
|
|
* Over structured values, operates element-wise.
|
|
|
|
* negate a = ~a + 1
|
|
|
|
*/
|
|
|
|
primitive negate : {a} (Arith a) => a -> a
|
|
|
|
|
|
|
|
/**
|
2016-05-05 02:26:36 +03:00
|
|
|
* Binary complement.
|
2015-06-09 01:58:46 +03:00
|
|
|
*/
|
2015-06-09 03:36:41 +03:00
|
|
|
primitive complement : {a} a -> a
|
2015-06-09 01:58:46 +03:00
|
|
|
|
2016-05-05 02:26:36 +03:00
|
|
|
/**
|
2016-08-13 03:12:34 +03:00
|
|
|
* Operator form of 'complement'.
|
2016-05-05 02:26:36 +03:00
|
|
|
*/
|
|
|
|
(~) : {a} a -> a
|
|
|
|
(~) = complement
|
|
|
|
|
2015-06-09 01:58:46 +03:00
|
|
|
/**
|
|
|
|
* Less-than. Only works on comparable arguments.
|
|
|
|
*/
|
2015-07-04 00:19:56 +03:00
|
|
|
primitive (<) : {a} (Cmp a) => a -> a -> Bit
|
2015-06-09 01:58:46 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Greater-than of two comparable arguments.
|
|
|
|
*/
|
2015-07-04 00:19:56 +03:00
|
|
|
primitive (>) : {a} (Cmp a) => a -> a -> Bit
|
2015-06-09 01:58:46 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Less-than or equal of two comparable arguments.
|
|
|
|
*/
|
2015-07-04 00:19:56 +03:00
|
|
|
primitive (<=) : {a} (Cmp a) => a -> a -> Bit
|
2015-06-09 01:58:46 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Greater-than or equal of two comparable arguments.
|
|
|
|
*/
|
2015-07-04 00:19:56 +03:00
|
|
|
primitive (>=) : {a} (Cmp a) => a -> a -> Bit
|
2015-06-09 01:58:46 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Compares any two values of the same type for equality.
|
|
|
|
*/
|
2015-07-04 00:19:56 +03:00
|
|
|
primitive (==) : {a} (Cmp a) => a -> a -> Bit
|
2015-06-09 01:58:46 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Compares any two values of the same type for inequality.
|
|
|
|
*/
|
2015-07-04 00:19:56 +03:00
|
|
|
primitive (!=) : {a} (Cmp a) => a -> a -> Bit
|
2015-06-09 01:58:46 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Compare the outputs of two functions for equality
|
|
|
|
*/
|
2015-07-04 00:19:56 +03:00
|
|
|
(===) : {a,b} (Cmp b) => (a -> b) -> (a -> b) -> (a -> Bit)
|
2015-06-09 01:58:46 +03:00
|
|
|
f === g = \ x -> f x == g x
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compare the outputs of two functions for inequality
|
|
|
|
*/
|
2015-07-04 00:19:56 +03:00
|
|
|
(!==) : {a,b} (Cmp b) => (a -> b) -> (a -> b) -> (a -> Bit)
|
2015-06-09 01:58:46 +03:00
|
|
|
f !== g = \x -> f x != g x
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the smaller of two comparable arguments.
|
|
|
|
*/
|
|
|
|
min : {a} (Cmp a) => a -> a -> a
|
|
|
|
min x y = if x < y then x else y
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the greater of two comparable arguments.
|
|
|
|
*/
|
|
|
|
max : {a} (Cmp a) => a -> a -> a
|
|
|
|
max x y = if x > y then x else y
|
|
|
|
|
2016-08-13 03:12:34 +03:00
|
|
|
/**
|
|
|
|
* Short-cutting boolean conjuction function.
|
|
|
|
* If the first argument is False, the second argument
|
|
|
|
* is not evaluated.
|
|
|
|
*/
|
|
|
|
(/\) : Bit -> Bit -> Bit
|
|
|
|
x /\ y = if x then y else False
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Short-cutting boolean disjuction function.
|
|
|
|
* If the first argument is True, the second argument
|
|
|
|
* is not evaluated.
|
|
|
|
*/
|
|
|
|
(\/) : Bit -> Bit -> Bit
|
|
|
|
x \/ y = if x then True else y
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Short-cutting logical implication.
|
|
|
|
* If the first argument is False, the second argument is
|
|
|
|
* not evaluated.
|
|
|
|
*/
|
|
|
|
(==>) : Bit -> Bit -> Bit
|
|
|
|
a ==> b = if a then b else True
|
|
|
|
|
2015-06-09 01:58:46 +03:00
|
|
|
/**
|
|
|
|
* Logical `and' over bits. Extends element-wise over sequences, tuples.
|
|
|
|
*/
|
|
|
|
primitive (&&) : {a} a -> a -> a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Logical `or' over bits. Extends element-wise over sequences, tuples.
|
|
|
|
*/
|
|
|
|
primitive (||) : {a} a -> a -> a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Logical `exclusive or' over bits. Extends element-wise over sequences, tuples.
|
|
|
|
*/
|
|
|
|
primitive (^) : {a} a -> a -> a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gives an arbitrary shaped value whose bits are all False.
|
|
|
|
* ~zero likewise gives an arbitrary shaped value whose bits are all True.
|
|
|
|
*/
|
|
|
|
primitive zero : {a} a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Left shift. The first argument is the sequence to shift, the second is the
|
|
|
|
* number of positions to shift by.
|
|
|
|
*/
|
|
|
|
primitive (<<) : {a, b, c} (fin b) => [a]c -> [b] -> [a]c
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Right shift. The first argument is the sequence to shift, the second is the
|
|
|
|
* number of positions to shift by.
|
|
|
|
*/
|
|
|
|
primitive (>>) : {a, b, c} (fin b) => [a]c -> [b] -> [a]c
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Left rotate. The first argument is the sequence to rotate, the second is the
|
|
|
|
* number of positions to rotate by.
|
|
|
|
*/
|
|
|
|
primitive (<<<) : {a, b, c} (fin a, fin b) => [a]c -> [b] -> [a]c
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Right rotate. The first argument is the sequence to rotate, the second is
|
|
|
|
* the number of positions to rotate by.
|
|
|
|
*/
|
|
|
|
primitive (>>>) : {a, b, c} (fin a, fin b) => [a]c -> [b] -> [a]c
|
|
|
|
|
|
|
|
primitive (#) : {front, back, a} (fin front) => [front]a -> [back]a
|
|
|
|
-> [front + back] a
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Split a sequence into a tuple of sequences.
|
|
|
|
*/
|
|
|
|
primitive splitAt : {front, back, a} (fin front) => [front + back]a
|
|
|
|
-> ([front]a, [back]a)
|
|
|
|
/**
|
|
|
|
* Joins sequences.
|
|
|
|
*/
|
|
|
|
primitive join : {parts, each, a} (fin each) => [parts][each]a
|
|
|
|
-> [parts * each]a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Splits a sequence into 'parts' groups with 'each' elements.
|
|
|
|
*/
|
|
|
|
primitive split : {parts, each, a} (fin each) => [parts * each]a
|
|
|
|
-> [parts][each]a
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reverses the elements in a sequence.
|
|
|
|
*/
|
|
|
|
primitive reverse : {a, b} (fin a) => [a]b -> [a]b
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Transposes an [a][b] matrix into a [b][a] matrix.
|
|
|
|
*/
|
|
|
|
primitive transpose : {a, b, c} [a][b]c -> [b][a]c
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Index operator. The first argument is a sequence. The second argument is
|
|
|
|
* the zero-based index of the element to select from the sequence.
|
|
|
|
*/
|
|
|
|
primitive (@) : {a, b, c} (fin c) => [a]b -> [c] -> b
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bulk index operator. The first argument is a sequence. The second argument
|
|
|
|
* is a sequence of the zero-based indices of the elements to select.
|
|
|
|
*/
|
|
|
|
primitive (@@) : {a, b, c, d} (fin d) => [a]b -> [c][d] -> [c]b
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reverse index operator. The first argument is a finite sequence. The second
|
|
|
|
* argument is the zero-based index of the element to select, starting from the
|
|
|
|
* end of the sequence.
|
|
|
|
*/
|
|
|
|
primitive (!) : {a, b, c} (fin a, fin c) => [a]b -> [c] -> b
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bulk reverse index operator. The first argument is a finite sequence. The
|
|
|
|
* second argument is a sequence of the zero-based indices of the elements to
|
2016-08-13 02:13:32 +03:00
|
|
|
* select, starting from the end of the sequence.
|
2015-06-09 01:58:46 +03:00
|
|
|
*/
|
|
|
|
primitive (!!) : {a, b, c, d} (fin a, fin d) => [a]b -> [c][d] -> [c]b
|
|
|
|
|
2016-08-10 00:47:43 +03:00
|
|
|
/**
|
|
|
|
* Update the given sequence with new value at the given index position.
|
|
|
|
* The first argument is a sequence. The second argument is the zero-based
|
|
|
|
* index of the element to update, starting from the front of the sequence.
|
|
|
|
* The third argument is the new element. The return value is the
|
|
|
|
* initial sequence updated so that the indicated index has the given value.
|
|
|
|
*/
|
|
|
|
primitive update : {a, b, c} (fin c) => [a]b -> [c] -> b -> [a]b
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the given sequence with new value at the given index position.
|
|
|
|
* The first argument is a sequence. The second argument is the zero-based
|
|
|
|
* index of the element to update, starting from the end of the sequence.
|
|
|
|
* The third argument is the new element. The return value is the
|
|
|
|
* initial sequence updated so that the indicated index has the given value.
|
|
|
|
*/
|
|
|
|
primitive updateEnd : {a, b, c} (fin a, fin c) => [a]b -> [c] -> b -> [a]b
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Perform a series of updates to a sequence. The first argument is
|
|
|
|
* the initial sequence to update. The second argument is a sequence
|
2016-08-17 00:36:46 +03:00
|
|
|
* of indices, and the third argument is a sequence of values.
|
2016-08-10 00:47:43 +03:00
|
|
|
* This function applies the 'update' function in sequence with the
|
|
|
|
* given update pairs.
|
|
|
|
*/
|
2016-08-17 00:36:46 +03:00
|
|
|
updates : {a,b,c,d} (fin c, fin d) => [a]b -> [d][c] -> [d]b -> [a]b
|
|
|
|
updates xs0 idxs vals = xss!0
|
2016-08-10 00:47:43 +03:00
|
|
|
where
|
|
|
|
xss = [ xs0 ] #
|
|
|
|
[ update xs i b
|
2016-08-17 00:36:46 +03:00
|
|
|
| xs <- xss
|
|
|
|
| i <- idxs
|
|
|
|
| b <- vals
|
|
|
|
]
|
2016-08-10 00:47:43 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Perform a series of updates to a sequence. The first argument is
|
|
|
|
* the initial sequence to update. The second argument is a sequence
|
2016-08-17 00:36:46 +03:00
|
|
|
* of indices, and the third argument is a sequence of values.
|
2016-08-10 00:47:43 +03:00
|
|
|
* This function applies the 'updateEnd' function in sequence with the
|
|
|
|
* given update pairs.
|
|
|
|
*/
|
2016-08-17 00:36:46 +03:00
|
|
|
updatesEnd : {a,b,c,d} (fin a, fin c, fin d) => [a]b -> [d][c] -> [d]b -> [a]b
|
|
|
|
updatesEnd xs0 idxs vals = xss!0
|
2016-08-10 00:47:43 +03:00
|
|
|
where
|
|
|
|
xss = [ xs0 ] #
|
|
|
|
[ updateEnd xs i b
|
2016-08-17 00:36:46 +03:00
|
|
|
| xs <- xss
|
|
|
|
| i <- idxs
|
|
|
|
| b <- vals
|
|
|
|
]
|
2016-08-10 00:47:43 +03:00
|
|
|
|
|
|
|
|
2015-06-09 01:58:46 +03:00
|
|
|
primitive fromThen : {first, next, bits, len}
|
|
|
|
( fin first, fin next, fin bits
|
|
|
|
, bits >= width first, bits >= width next
|
|
|
|
, lengthFromThen first next bits == len) => [len][bits]
|
|
|
|
|
|
|
|
primitive fromTo : {first, last, bits} (fin last, fin bits, last >= first,
|
|
|
|
bits >= width last) => [1 + (last - first)][bits]
|
|
|
|
|
|
|
|
primitive fromThenTo : {first, next, last, bits, len} (fin first, fin next,
|
|
|
|
fin last, fin bits, bits >= width first,
|
|
|
|
bits >= width next, bits >= width last,
|
|
|
|
lengthFromThenTo first next last == len) => [len][bits]
|
|
|
|
|
|
|
|
primitive infFrom : {bits} (fin bits) => [bits] -> [inf][bits]
|
|
|
|
|
|
|
|
primitive infFromThen : {bits} (fin bits) => [bits] -> [bits] -> [inf][bits]
|
|
|
|
|
|
|
|
primitive error : {at, len} (fin len) => [len][8] -> at
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-12-31 20:46:13 +03:00
|
|
|
* Performs multiplication of polynomials over GF(2).
|
2015-06-09 01:58:46 +03:00
|
|
|
*/
|
2016-09-21 01:13:40 +03:00
|
|
|
primitive pmult : {a, b} (fin a, fin b) => [1 + a] -> [1 + b] -> [1 + a + b]
|
2015-06-09 01:58:46 +03:00
|
|
|
|
|
|
|
/**
|
2015-12-31 20:46:13 +03:00
|
|
|
* Performs division of polynomials over GF(2).
|
2015-06-09 01:58:46 +03:00
|
|
|
*/
|
|
|
|
primitive pdiv : {a, b} (fin a, fin b) => [a] -> [b] -> [a]
|
|
|
|
|
|
|
|
/**
|
2015-12-31 20:46:13 +03:00
|
|
|
* Performs modulus of polynomials over GF(2).
|
2015-06-09 01:58:46 +03:00
|
|
|
*/
|
|
|
|
primitive pmod : {a, b} (fin a, fin b) => [a] -> [1 + b] -> [b]
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generates random values from a seed. When called with a function, currently
|
|
|
|
* generates a function that always returns zero.
|
|
|
|
*/
|
2016-01-20 05:17:34 +03:00
|
|
|
primitive random : {a} [256] -> a
|
2015-06-06 01:47:12 +03:00
|
|
|
|
2014-04-18 02:34:25 +04:00
|
|
|
type String n = [n][8]
|
|
|
|
type Word n = [n]
|
|
|
|
type Char = [8]
|
|
|
|
|
|
|
|
take : {front,back,elem} (fin front) => [front + back] elem -> [front] elem
|
|
|
|
take (x # _) = x
|
|
|
|
|
|
|
|
drop : {front,back,elem} (fin front) => [front + back] elem -> [back] elem
|
|
|
|
drop ((_ : [front] _) # y) = y
|
|
|
|
|
|
|
|
tail : {a, b} [1 + a]b -> [a]b
|
|
|
|
tail xs = drop`{1} xs
|
|
|
|
|
|
|
|
width : {bits,len,elem} (fin len, fin bits, bits >= width len) => [len] elem -> [bits]
|
|
|
|
width _ = `len
|
|
|
|
|
|
|
|
undefined : {a} a
|
|
|
|
undefined = error "undefined"
|
|
|
|
|
|
|
|
groupBy : {each,parts,elem} (fin each) =>
|
|
|
|
[parts * each] elem -> [parts][each]elem
|
|
|
|
groupBy = split`{parts=parts}
|
2016-05-05 03:54:08 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Define the base 2 logarithm function in terms of width
|
|
|
|
*/
|
|
|
|
type lg2 n = width (max n 1 - 1)
|
2016-05-13 04:44:06 +03:00
|
|
|
|
|
|
|
/**
|
2016-07-14 00:16:33 +03:00
|
|
|
* Debugging function for tracing. The first argument is a string,
|
|
|
|
* which is prepended to the printed value of the second argument.
|
|
|
|
* This combined string is then printed when the trace function is
|
|
|
|
* evaluated. The return value is equal to the third argument.
|
|
|
|
*
|
|
|
|
* The exact timing and number of times the trace message is printed
|
|
|
|
* depend on the internal details of the Cryptol evaluation order,
|
|
|
|
* which are unspecified. Thus, the output produced by this
|
|
|
|
* operation may be difficult to predict.
|
2016-05-13 04:44:06 +03:00
|
|
|
*/
|
|
|
|
primitive trace : {n, a, b} [n][8] -> a -> b -> b
|
|
|
|
|
2016-07-14 00:16:33 +03:00
|
|
|
/**
|
|
|
|
* Debugging function for tracing values. The first argument is a string,
|
|
|
|
* which is prepended to the printed value of the second argument.
|
|
|
|
* This combined string is then printed when the trace function is
|
|
|
|
* evaluated. The return value is equal to the second argument.
|
|
|
|
*
|
|
|
|
* The exact timing and number of times the trace message is printed
|
|
|
|
* depend on the internal details of the Cryptol evaluation order,
|
|
|
|
* which are unspecified. Thus, the output produced by this
|
|
|
|
* operation may be difficult to predict.
|
|
|
|
*/
|
2016-05-14 03:21:51 +03:00
|
|
|
traceVal : {n, a} [n][8] -> a -> a
|
2016-05-13 04:44:06 +03:00
|
|
|
traceVal msg x = trace msg x x
|