aboutsummaryrefslogtreecommitdiff
path: root/src/Assembly/WordBounds.v
blob: e05fcb1d4dcc3a37260bd8d6c836c62dfa759c6d (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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
Require Import Bedrock.Word.
Import BinNums PArith.BinPos NArith.BinNat NArith.Ndigits.

Definition wordUn (f : N -> N) {sz : nat} (x : word sz) :=
	NToWord sz (f (wordToN x)).
Definition wshr {l} n := @wordUn (fun x => N.shiftr x n) l.
Lemma wshr_test : (wordToN (wshr 3 (NToWord 32 (128- 19)))) = 13%N.
	reflexivity.
Qed.

Module WordBoundsExamples.
  Definition u31 := word 31.
  Definition U31 := NToWord 31.
  Definition u64 := word 64.
  Definition U64 := NToWord 64.

	Definition c2  : u64 := NToWord _  2.
	Definition c19_31 : u31 := NToWord _ 19.
	Definition c19 : u64 := NToWord _ 19.
	Definition c38 : u64 := NToWord _ 38.
	Definition t25_31 : u31 := NToWord _ (Npos (2^25)).
	Definition t26_31 : u31 := NToWord _ (Npos (2^26)).
	Definition t25 : u64 := NToWord _ (Npos (2^25)).
	Definition t26 : u64 := NToWord _ (Npos (2^26)).
	Definition t27 : u64 := NToWord _ (Npos (2^26)).
	Definition m25 : u64 := t25^-(NToWord _ 1).
	Definition m26 : u64 := t26^-(NToWord _ 1).
	Definition r25 (hSk hk:u64) : (u64 * u64) := (hSk ^+ wshr 25 hk, wand m25 hk).
	Definition r26 (hSk hk:u64) : (u64 * u64) := (hSk ^+ wshr 26 hk, wand m26 hk).
	Definition r25mod (hSk hk:u64) : (u64 * u64) := (hSk ^+ c19^*wshr 25 hk, wand m25 hk).

	Lemma simple_add_rep : forall (a b c d:N),
		(a < Npos(2^29) -> b < Npos(2^29) -> c < Npos(2^29) -> d < Npos(2^29))%N ->
		wordToN(U31 a ^+ U31 b ^+ U31 c ^+ U31 d) = (a + b + c + d)%N.
	Admitted.

	Lemma simple_add_bound : forall (a b c d:u64),
		a < t25 -> b < t25 -> c < t25 -> d < t25 ->
		(a ^+ b ^+ c ^+ d) < t27.
	Admitted.

  (* the bounds can as well be stated in N if the _rep lemma works.
  I am not sure whether it is a better idea to propagate the bounds in word or
  in N, though -- proving rep requires propagating bounds for the subexpressions.
  *)

	Lemma simple_linear_rep : forall (a b:N), (a < Npos(2^25) + Npos(2^26) -> b < Npos(2^25))%N -> 
		wordToN((U31 a)^*c19_31 ^+ U31 b) = (a*19 + b)%N.
	Admitted.

	Lemma simple_linear_bound : forall (a b:u31), a < t25_31 ^+ t26_31 -> b < t25_31 -> 
		a^*c19_31 ^+ b < (NToWord _ 1946157056). (* (2**26+2**25)*19 + 2**25 = 1946157056 *)
	Admitted.

	Lemma simple_mul_carry_rep : forall (a b c:N), (a < Npos(2^26) -> b < Npos(2^26) -> c < Npos(2^26))%N ->
		wordToN(wshr 26 (U64 a ^* U64 b) ^+ U64 c) = ((a*b)/(2^26) + c)%N.
  Admitted.

	Lemma simple_mul_carry_bound : forall (a b c:u64), a < t26 -> b < t26 -> c < t26 ->
		wshr 26 (a ^* b) ^+ c < t27.
	Admitted.

	Lemma simple_mul_reduce_rep : forall (a b c:N), (a < Npos(2^26) -> b < Npos(2^26))%N ->
		wordToN(wand m26 (U64 a ^* U64 b)) = ((a*b) mod (2^26) + c)%N.
  Admitted.

	Lemma sandy2x_bound : forall
		(* this example is transcribed by hand from <https://eprint.iacr.org/2015/943.pdf> section 2.2.
			 it is very representative of the bounds check / absence-of-overflow proofs we actually
			 want to do. However, given its size, presence of transcription errors is totally plausible.
       A corresponding _rep proof will also necessary.*)
		(f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 : u64)
		(g0 g1 g2 g3 g4 g5 g6 g7 g8 g9 : u64),
  	f0 < t26 -> g0 < t26 ->
  	f1 < t25 -> g1 < t25 ->
  	f2 < t26 -> g2 < t26 ->
  	f3 < t25 -> g3 < t25 ->
  	f4 < t26 -> g4 < t26 ->
  	f5 < t25 -> g5 < t25 ->
  	f6 < t26 -> g6 < t26 ->
  	f7 < t25 -> g7 < t25 ->
  	f8 < t26 -> g8 < t26 ->
  	f9 < t25 -> g9 < t25 ->

		let h0 := f0^*g0 ^+ c38^*f1^*g9 ^+ c19^*f2^*g8 ^+  c38^*f3^*g7 ^+ c19^*f4^*g6 ^+ c38^*f5^*g5 ^+ c19^*f6^*g4 ^+ c38^*f7^*g3 ^+ c19^*f8^*g2 ^+ c38^*f9^*g1 in
		let h1 := f0^*g1 ^+      f1^*g0 ^+ c19^*f2^*g9 ^+  c19^*f3^*g8 ^+ c19^*f4^*g7 ^+ c19^*f5^*g6 ^+ c19^*f6^*g5 ^+ c19^*f7^*g4 ^+ c19^*f8^*g3 ^+ c19^*f9^*g2 in
		let h2 := f0^*g2 ^+ c2^* f1^*g1 ^+      f2^*g0 ^+  c38^*f3^*g9 ^+ c19^*f4^*g8 ^+ c38^*f5^*g7 ^+ c19^*f6^*g6 ^+ c38^*f7^*g5 ^+ c19^*f8^*g4 ^+ c38^*f9^*g3 in
		let h3 := f0^*g3 ^+      f1^*g2 ^+      f2^*g1 ^+       f3^*g0 ^+ c19^*f4^*g9 ^+ c19^*f5^*g8 ^+ c19^*f6^*g7 ^+ c19^*f7^*g6 ^+ c19^*f8^*g5 ^+ c19^*f9^*g4 in
		let h4 := f0^*g4 ^+ c2^* f1^*g3 ^+      f2^*g2 ^+  c2^* f3^*g1 ^+      f4^*g0 ^+ c38^*f5^*g9 ^+ c19^*f6^*g8 ^+ c38^*f7^*g7 ^+ c19^*f8^*g6 ^+ c38^*f9^*g5 in
		let h5 := f0^*g5 ^+      f1^*g4 ^+      f2^*g3 ^+       f3^*g2 ^+      f4^*g1 ^+      f5^*g0 ^+ c19^*f6^*g9 ^+ c19^*f7^*g8 ^+ c19^*f8^*g7 ^+ c19^*f9^*g6 in
		let h6 := f0^*g6 ^+ c2^* f1^*g5 ^+      f2^*g4 ^+  c2^* f3^*g3 ^+      f4^*g2 ^+ c2^* f5^*g1 ^+      f6^*g0 ^+ c38^*f7^*g9 ^+ c19^*f8^*g8 ^+ c38^*f9^*g7 in
		let h7 := f0^*g7 ^+      f1^*g6 ^+      f2^*g5 ^+       f3^*g4 ^+      f4^*g3 ^+      f5^*g2 ^+      f6^*g1 ^+      f7^*g0 ^+ c19^*f8^*g9 ^+ c19^*f9^*g8 in
		let h8 := f0^*g8 ^+ c2^* f1^*g7 ^+      f2^*g6 ^+  c2^* f3^*g5 ^+      f4^*g4 ^+ c2^* f5^*g3 ^+      f6^*g2 ^+ c2^* f7^*g1 ^+      f8^*g0 ^+ c38^*f9^*g9 in
		let h9 := f0^*g9 ^+      f1^*g8 ^+      f2^*g7 ^+       f3^*g6 ^+      f4^*g5 ^+      f5^*g4 ^+      f6^*g3 ^+      f7^*g2 ^+      f8^*g1 ^+      f9^*g0 in
		
		let (h1_1, h0_1) := r26 h1 h0 in
		let (h2_1, h1_2) := r25 h2 h1_1 in
		let (h3_1, h2_2) := r26 h3 h2_1 in
		let (h4_1, h3_2) := r25 h4 h3_1 in

		let (h6_1, h5_1) := r25 h6 h5 in
		let (h7_1, h6_2) := r26 h7 h6_1 in
		let (h8_1, h7_2) := r25 h8 h7_1 in
		let (h9_1, h8_2) := r26 h9 h8_1 in
		let (h0_2, h9_2) := r25mod h0_1 h9_1 in
		let (h1_3, h0_2) := r26 h1_2 h0_1 in

		let (h5_2, h4_2) := r26 h5_1 h4_1 in
		let (h6_2, h5_3) := r25 h6_1 h5_2 in

  	h0_2 < t26 /\
  	h1_3 < t27 /\
  	h2_2 < t26 /\
  	h3_2 < t25 /\
  	h4_2 < t26 /\
  	h5_3 < t25 /\
  	h6_2 < t27 /\
  	h7_2 < t25 /\
  	h8_2 < t26 /\
  	h9_2 < t25.
	Admitted.
End WordBoundsExamples.