summaryrefslogtreecommitdiff
path: root/lib/crypto/ct.myr
blob: 80ad13e5f23e8b72f43b67ba3cbb929ac10c6c46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use std

pkg crypto =
	/* These functions require unsigned inputs in order to work correctly */
	generic not	: (a : @t -> @t)	:: integral,numeric @t
	generic eq	: (a : @t, b : @t -> @t)	:: integral,numeric @t
	generic ne	: (a : @t, b : @t -> @t)	:: integral,numeric @t
	generic gt	: (a : @t, b : @t -> @t)	:: integral,numeric @t
	generic lt	: (a : @t, b : @t -> @t)	:: integral,numeric @t
	generic ge	: (a : @t, b : @t -> @t)	:: integral,numeric @t
	generic le	: (a : @t, b : @t -> @t)	:: integral,numeric @t
	generic mux	: (x : @t, a : @t, b : @t ->@t)	:: integral,numeric @t
	generic min	: (a : @t, b : @t -> @t)	:: integral,numeric @t
	generic max	: (a : @t, b : @t -> @t)	:: integral,numeric @t
	const bufeq	: (a : byte[:], b : byte[:] -> bool)
;;

generic not = {a : @t :: integral,numeric @t
	-> a ^ 1
}

generic eq = {a : @t, b : @t :: integral,numeric @t
	const nshift = 8*sizeof(@t) - 1
	var q = a ^ b
	-> ((q | -q) >> nshift)^1
}

generic gt = {a : @t, b : @t :: integral,numeric @t
	/* 
	  3 cases:
	  - both top bits unset => check if result is -ve (top bit set)
	  - one top bit set: 	=> one with top bit set is >
	  - both top bits set:	=> subtract, check if result is -ve
	*/
	const nshift = 8*sizeof(@t) - 1
	var z = (b - a) 
	-> (z ^ ((a ^ b) & (a ^ z))) >> nshift;
}

generic ge = {a, b
	-> lt(a, b) ^ 1
}

generic lt = {a, b
	const nshift = 8*sizeof(@t) - 1
	var z = (a - b) 
	-> (z ^ ((b ^ a) & (b ^ a))) >> nshift;
}

generic le = {a, b
	-> gt(a, b) ^ 1
}

generic ne = {a, b
	const nshift = 8*sizeof(@t) - 1
	var q = a ^ b
	-> (q | -q) >> nshift
}

generic mux = {c, a, b
	-> b ^ (-c & (a ^ b))
}

generic min = {a, b
	var x

	x = lt(a, b)
	-> mux(x, a, b)
}

generic max = {a, b
	var x

	x = lt(a, b)
	-> mux(x, b, a)
}

const bufeq = {a, b
	var r, n

	r = 1
	n = min(a.len, b.len)
	for var i = 0; i < n; i++
		r = mux(r, eq(a[i], b[i]), r)
	;;
	-> (r : bool)
}