1
Simple High-Level Code For Cryptographic Arithmetic – With Proofs, Without Compromises
Andres Erbsen, Jade Philipoom, Jason Gross, Robert Sloan, Adam Chlipala MIT CSAIL
g i t h u b . c
- m
/ m i t
- p
l v / fi a t
- c
Simple High-Level Code For Cryptographic Arithmetic With Proofs, - - PowerPoint PPT Presentation
Simple High-Level Code For Cryptographic Arithmetic With Proofs, Without Compromises Andres Erbsen, Jade Philipoom, Jason Gross, Robert Sloan, Adam Chlipala MIT CSAIL g i t h u b . c o m / m i t - p l v / fi a t - c
1
2
– TLS, Signal, SSH...
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Generic (GMP)
Our library
Specialized C
Specialized assembly 121444 152195 154982 ~750000
25
– m
2 5 5
2 5 6
4
1 9 6
3
1 2 8
2
6 4
1
– m
1 2 7
1 2 7
3
8 5
2
4 3
1
43 42 42 bits
26
– m
2 5 5
2 5 6
4
1 9 6
3
1 2 8
2
6 4
1
– m
1 2 7
1 2 7
3
8 5
2
4 3
1
43 42 42 bits
27
mulmod a b := a * b mod m
Let reduce s c p := let (lo, hi) := split s p in add lo (mul c hi).
Proof
28
mulmod a b := a * b mod m
Let reduce s c p := let (lo, hi) := split s p in add lo (mul c hi).
Proof
29
2
30
2
31
a = [(100,3); (10,2); (1,1)] b = [(10,7); (1,6)] 3 2 1 18 12 6 6 21 14 7 7 ab = [(100, 18); (10, 12); (1, 6); (1000,21);(100, 14);(10,7)]
Definition mul (p q : list (Z*Z)) : list (Z*Z) := concat (map (fun ‘(a, x) => map (fun ‘(b, y) => (a*b, x*y)) q) p). Lemma eval_map_mul a x q: eval (map (fun ‘(b, y)=>(a*b, x*y)) q)=a*x*eval q.
Hint Rewrite eval_map_mul : push. Lemma eval_mul : forall p q, eval (mul p q) = eval p * eval q.
32
– cbv -[blacklist] in (mul [(1,x);..] ..)
33
Definition mul (p q : list (Z*Z)) : list (Z*Z) := concat (map (fun ‘(a, x) => map (fun ‘(b, y) => (a*b, x*y)) q) p). Lemma eval_map_mul a x q: eval (map (fun ‘(b, y)=>(a*b, x*y)) q)=a*x*eval q.
Hint Rewrite eval_map_mul : push. Lemma eval_mul : forall p q, eval (mul p q) = eval p * eval q.
Annotated run-time operation
34
Eval cbv -[runtime_mul] in fun a0 a1 a2 b0 b1 b2 => mul [(1, a0); (10, a1); (100, a2)] [(1, b0); (10, b1); (100, b2)]. = fun a0 a1 a2 b0 b1 b2 => [ (1, a0*b0); (10, a0*b1); (100, a0*b2); (10, a1*b0); (100, a1*b1); (1000, a1*b2); (100, a2*b0); (1000, a2*b1); (10000, a2*b2)]
fun a0 a1 a2 b0 b1 b2 => [(1, a0*b0); (10, a0*b1 + a1*b0); (100, a0*b2+a1*b1+a2*b0); (1000, a1*b2 + a2*b1); (10000, a2*b2)]
35
→ Assign each term to the correct slot
– Disallow? But proofs – Useful to handle for mixed-radix representations
36
→ Assign each term to the correct slot
– Disallow? But proofs – Useful to handle for mixed-radix representations
37
→ Assign each term to the correct slot
– Disallow? But proofs – Useful to handle for mixed-radix representations
38
39
40
41
42
Eval cbv -[runtime_mul runtime_add] in (mulmod (n:=10) w (2 ^ 255) [(1, 19)] (f9, f8, f7, f6, f5, f4, f3, f2, f1, f0) (g9, g8, g7, g6, g5, g4, g3, g2, g1, g0)). ring_simplify_subterms.
(* ?fg = (f0*g9+ f1*g8+ f2*g7+ f3*g6+ f4*g5+ f5*g4+ f6*g3+ f7*g2+ f8*g1+ f9*g0, f0*g8+ 2*f1*g7+ f2*g6+ 2*f3*g5+ f4*g4+ 2*f5*g3+ f6*g2+ 2*f7*g1+ f8*g0+ 38*f9*g9, f0*g7+ f1*g6+ f2*g5+ f3*g4+ f4*g3+ f5*g2+ f6*g1+ f7*g0+ 19*f8*g9+ 19*f9*g8, f0*g6+ 2*f1*g5+ f2*g4+ 2*f3*g3+ f4*g2+ 2*f5*g1+ f6*g0+ 38*f7*g9+ 19*f8*g8+ 38*f9*g7, f0*g5+ f1*g4+ f2*g3+ f3*g2+ f4*g1+ f5*g0+ 19*f6*g9+ 19*f7*g8+ 19*f8*g7+ 19*f9*g6, f0*g4+ 2*f1*g3+ f2*g2+ 2*f3*g1+ f4*g0+ 38*f5*g9+ 19*f6*g8+ 38*f7*g7+ 19*f8*g6+ 38*f9*g5, f0*g3+ f1*g2+ f2*g1+ f3*g0+ 19*f4*g9+ 19*f5*g8+ 19*f6*g7+ 19*f7*g6+ 19*f8*g5+ 19*f9*g4, f0*g2+ 2*f1*g1+ f2*g0+ 38*f3*g9+ 19*f4*g8+ 38*f5*g7+ 19*f6*g6+ 38*f7*g5+ 19*f8*g4+ 38*f9*g3, f0*g1+ f1*g0+ 19*f2*g9+ 19*f3*g8+ 19*f4*g7+ 19*f5*g6+ 19*f6*g5+ 19*f7*g4+ 19*f8*g3+ 19*f9*g2, f0*g0+ 38*f1*g9+ 19*f2*g8+ 38*f3*g7+ 19*f4*g6+ 38*f5*g5+ 19*f6*g4+ 38*f7*g3+ 19*f8*g2+ 38*f9*g1) *)
43
Eval cbv -[runtime_mul runtime_add] in (mulmod (n:=10) w (2 ^ 255) [(1, 19)] (f9, f8, f7, f6, f5, f4, f3, f2, f1, f0) (g9, g8, g7, g6, g5, g4, g3, g2, g1, g0)). ring_simplify_subterms.
(* ?fg = (f0*g9+ f1*g8+ f2*g7+ f3*g6+ f4*g5+ f5*g4+ f6*g3+ f7*g2+ f8*g1+ f9*g0, f0*g8+ 2*f1*g7+ f2*g6+ 2*f3*g5+ f4*g4+ 2*f5*g3+ f6*g2+ 2*f7*g1+ f8*g0+ 38*f9*g9, f0*g7+ f1*g6+ f2*g5+ f3*g4+ f4*g3+ f5*g2+ f6*g1+ f7*g0+ 19*f8*g9+ 19*f9*g8, f0*g6+ 2*f1*g5+ f2*g4+ 2*f3*g3+ f4*g2+ 2*f5*g1+ f6*g0+ 38*f7*g9+ 19*f8*g8+ 38*f9*g7, f0*g5+ f1*g4+ f2*g3+ f3*g2+ f4*g1+ f5*g0+ 19*f6*g9+ 19*f7*g8+ 19*f8*g7+ 19*f9*g6, f0*g4+ 2*f1*g3+ f2*g2+ 2*f3*g1+ f4*g0+ 38*f5*g9+ 19*f6*g8+ 38*f7*g7+ 19*f8*g6+ 38*f9*g5, f0*g3+ f1*g2+ f2*g1+ f3*g0+ 19*f4*g9+ 19*f5*g8+ 19*f6*g7+ 19*f7*g6+ 19*f8*g5+ 19*f9*g4, f0*g2+ 2*f1*g1+ f2*g0+ 38*f3*g9+ 19*f4*g8+ 38*f5*g7+ 19*f6*g6+ 38*f7*g5+ 19*f8*g4+ 38*f9*g3, f0*g1+ f1*g0+ 19*f2*g9+ 19*f3*g8+ 19*f4*g7+ 19*f5*g6+ 19*f6*g5+ 19*f7*g4+ 19*f8*g3+ 19*f9*g2, f0*g0+ 38*f1*g9+ 19*f2*g8+ 38*f3*g7+ 19*f4*g6+ 38*f5*g5+ 19*f6*g4+ 38*f7*g3+ 19*f8*g2+ 38*f9*g1) *)
44
0 ≤ f0, f2, f4, f6, f8 ≤ 1.25*2^26 (uint32_t) 0 ≤ f1, f3, f5, f7, f9 ≤ 1.25*2^25 (uint32_t) 0 ≤ g0, g2, g4, g6, g8 ≤ 1.25*2^26 (uint32_t) 0 ≤ g1, g3, g5, g7, g9 ≤ 1.25*2^25 (uint32_t)
f0*g1+ f1*g0+ 19*f2*g9+ 19*f3*g8+ 19*f4*g7+ 19*f5*g6+ 19*f6*g5+ 19*f7*g4+ 19*f8*g3+ 19*f9*g2 ≤2^52
45
≤2^52 uint64_t
0 ≤ f0, f2, f4, f6, f8 ≤ 1.25*2^26 (uint32_t) 0 ≤ f1, f3, f5, f7, f9 ≤ 1.25*2^25 (uint32_t) 0 ≤ g0, g2, g4, g6, g8 ≤ 1.25*2^26 (uint32_t) 0 ≤ g1, g3, g5, g7, g9 ≤ 1.25*2^25 (uint32_t)
f0*g1+ f1*g0+ 19*f2*g9+ 19*f3*g8+ 19*f4*g7+ 19*f5*g6+ 19*f6*g5+ 19*f7*g4+ 19*f8*g3+ 19*f9*g2
46
≤2^52 uint64_t ≤2^52 ≤2^52 uint64_t
0 ≤ f0, f2, f4, f6, f8 ≤ 1.25*2^26 (uint32_t) 0 ≤ f1, f3, f5, f7, f9 ≤ 1.25*2^25 (uint32_t) 0 ≤ g0, g2, g4, g6, g8 ≤ 1.25*2^26 (uint32_t) 0 ≤ g1, g3, g5, g7, g9 ≤ 1.25*2^25 (uint32_t)
f0*g1+ f1*g0+ 19*f2*g9+ 19*f3*g8+ 19*f4*g7+ 19*f5*g6+ 19*f6*g5+ 19*f7*g4+ 19*f8*g3+ 19*f9*g2
47
≤2^52 uint64_t ≤2^56 uint64_t ≤2^52 uint64_t
0 ≤ f0, f2, f4, f6, f8 ≤ 1.25*2^26 (uint32_t) 0 ≤ f1, f3, f5, f7, f9 ≤ 1.25*2^25 (uint32_t) 0 ≤ g0, g2, g4, g6, g8 ≤ 1.25*2^26 (uint32_t) 0 ≤ g1, g3, g5, g7, g9 ≤ 1.25*2^25 (uint32_t)
f0*g1+ f1*g0+ 19*f2*g9+ 19*f3*g8+ 19*f4*g7+ 19*f5*g6+ 19*f6*g5+ 19*f7*g4+ 19*f8*g3+ 19*f9*g2
48
≤2^52 ≤2^56 ≤2^52 ≤2^57 uint64_t
0 ≤ f0, f2, f4, f6, f8 ≤ 1.25*2^26 (uint32_t) 0 ≤ f1, f3, f5, f7, f9 ≤ 1.25*2^25 (uint32_t) 0 ≤ g0, g2, g4, g6, g8 ≤ 1.25*2^26 (uint32_t) 0 ≤ g1, g3, g5, g7, g9 ≤ 1.25*2^25 (uint32_t)
f0*g1+ f1*g0+ 19*f2*g9+ 19*f3*g8+ 19*f4*g7+ 19*f5*g6+ 19*f6*g5+ 19*f7*g4+ 19*f8*g3+ 19*f9*g2
49
≤2^59 uint64_t ≤2^52 ≤2^56 ≤2^52 ≤2^57
0 ≤ f0, f2, f4, f6, f8 ≤ 1.25*2^26 (uint32_t) 0 ≤ f1, f3, f5, f7, f9 ≤ 1.25*2^25 (uint32_t) 0 ≤ g0, g2, g4, g6, g8 ≤ 1.25*2^26 (uint32_t) 0 ≤ g1, g3, g5, g7, g9 ≤ 1.25*2^25 (uint32_t)
f0*g1+ f1*g0+ 19*f2*g9+ 19*f3*g8+ 19*f4*g7+ 19*f5*g6+ 19*f6*g5+ 19*f7*g4+ 19*f8*g3+ 19*f9*g2
50
Carrying: x >> 26 x & ((1<<26)-1)
≤2^33 <2^26
0 ≤ f0, f2, f4, f6, f8 ≤ 1.25*2^26 (uint32_t) 0 ≤ f1, f3, f5, f7, f9 ≤ 1.25*2^25 (uint32_t) 0 ≤ g0, g2, g4, g6, g8 ≤ 1.25*2^26 (uint32_t) 0 ≤ g1, g3, g5, g7, g9 ≤ 1.25*2^25 (uint32_t)
f0*g1+ f1*g0+ 19*f2*g9+ 19*f3*g8+ 19*f4*g7+ 19*f5*g6+ 19*f6*g5+ 19*f7*g4+ 19*f8*g3+ 19*f9*g2 ≤2^59 uint64_t ≤2^52 ≤2^56 ≤2^52 ≤2^57
51
52
– Translation validation for human-compiled variants?
53