proofs/crypto/secp256k1/reducek.bend
bend-collections-laws-crypto@1.0.0.0 · 155 lines · 19 definitions
1
2import Base
3import bend-collections-laws-crypto@1.0.0.0/spec/lib/common.bend as C
4import bend-collections-laws-crypto@1.0.0.0/spec/crypto/secp256k1/field.bend as FS
5import bend-collections-laws-crypto@1.0.0.0/src/crypto/secp256k1/limbs.bend as L
6import bend-collections-laws-crypto@1.0.0.0/proofs/lib/nat.bend as N
7import bend-collections-laws-crypto@1.0.0.0/proofs/lib/logic.bend as Lg
8import bend-collections-laws-crypto@1.0.0.0/proofs/lib/lemmas/proofs/nat_algebra.bend as NA
9import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/secp256k1/limbs.bend as LV
10import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/secp256k1/fprot.bend as FR
11import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/secp256k1/ineq.bend as I
12import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/secp256k1/reduce.bend as R
13
14
15
16
17
18
19
20
21def x0_lo(+one: Nat, +h1: {one == 1n : Nat}, +xs: List<&2, Nat>) -> {FS.limbs16(one, 16n, L.take(16n, L.carry(32n, xs, 0n))) == True{} : Bool}:
22 R.round_lo(one, h1, xs)
23
24
25def addmul(+t: Nat, +cv: Nat) -> {Nat.add(t, Nat.mul(t, cv)) == Nat.mul(1n+cv, t) : Nat}:
26 %Equal.sym(Nat, Nat.mul(t, cv), Nat.mul(cv, t), NA.mul_comm(t, cv)) : {Nat.add(t, _) == Nat.mul(1n+cv, t) : Nat}
27 {==}
28
29
30
31def red3_x3(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>, +xs: List<&2, Nat>, +hb: {Nat.is_le(Nat.add(Nat.mul(1n+LV.ev(c), LV.ev(c)), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {Nat.is_lt(LV.ev(L.rounds(3n, c, L.carry(32n, xs, 0n))), C.shift(256n, one)) == True{} : Bool}:
32 +t = C.shift(256n, one)
33 +cv = LV.ev(c)
34 +x0 = L.carry(32n, xs, 0n)
35 +x1 = L.carry(32n, L.fold(c, x0), 0n)
36 +x2 = L.carry(32n, L.fold(c, x1), 0n)
37 +h0 = I.lt_subst_l(LV.ev(xs), LV.ev(x0), Nat.mul(t, t), Equal.sym(Nat, LV.ev(x0), LV.ev(xs), LV.carry_v(32n, xs, 0n)), hx)
38 +h1b = R.round_lt1(one, h1, c, x0, t, x0_lo(one, h1, xs), h0)
39 +h1c = I.lt_subst_r(LV.ev(x1), Nat.add(t, Nat.mul(t, cv)), Nat.mul(1n+cv, t), addmul(t, cv), h1b)
40 +h2b = R.round_lt1(one, h1, c, x1, 1n+cv, R.round_lo(one, h1, L.fold(c, x0)), h1c)
41 +h3 = R.fold_lt2(one, h1, c, x2, Nat.mul(1n+cv, cv), hb, R.round_lo(one, h1, L.fold(c, x1)), h2b)
42 %Equal.sym(Nat, LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n)), LV.ev(L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n))), R.round_v(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n))) : {Nat.is_lt(_, C.shift(256n, one)) == True{} : Bool}
43 h3
44
45def red3_mod(+one: Nat, +h1: {one == 1n : Nat}, +mp: Nat, +c: List<&2, Nat>, +hm: {Nat.add(1n+mp, LV.ev(c)) == C.shift(256n, one) : Nat}, +xs: List<&2, Nat>) -> {Nat.mod(LV.ev(L.rounds(3n, c, L.carry(32n, xs, 0n))), 1n+mp) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}:
46 +x0 = L.carry(32n, xs, 0n)
47 +x1 = L.carry(32n, L.fold(c, x0), 0n)
48 +x2 = L.carry(32n, L.fold(c, x1), 0n)
49 %Equal.sym(Nat, Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n)), 1n+mp), Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 1n+mp), R.round_mod(one, h1, mp, c, hm, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n))) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
50 %Equal.sym(Nat, Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 1n+mp), Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 1n+mp), R.round_mod(one, h1, mp, c, hm, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n))) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
51 %Equal.sym(Nat, Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 1n+mp), Nat.mod(LV.ev(L.carry(32n, xs, 0n)), 1n+mp), R.round_mod(one, h1, mp, c, hm, L.carry(32n, xs, 0n))) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
52 %Equal.sym(Nat, LV.ev(L.carry(32n, xs, 0n)), Nat.add(0n, LV.ev(xs)), LV.carry_v(32n, xs, 0n)) : {Nat.mod(_, 1n+mp) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
53 {==}
54
55def red4_mod(+one: Nat, +h1: {one == 1n : Nat}, +mp: Nat, +c: List<&2, Nat>, +hm: {Nat.add(1n+mp, LV.ev(c)) == C.shift(256n, one) : Nat}, +xs: List<&2, Nat>) -> {Nat.mod(LV.ev(L.rounds(4n, c, L.carry(32n, xs, 0n))), 1n+mp) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}:
56 %Equal.sym(Nat, Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n)), 0n)), 1n+mp), Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n)), 1n+mp), R.round_mod(one, h1, mp, c, hm, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n))) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
57 %Equal.sym(Nat, Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n)), 1n+mp), Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 1n+mp), R.round_mod(one, h1, mp, c, hm, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n))) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
58 %Equal.sym(Nat, Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 1n+mp), Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 1n+mp), R.round_mod(one, h1, mp, c, hm, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n))) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
59 %Equal.sym(Nat, Nat.mod(LV.ev(L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 1n+mp), Nat.mod(LV.ev(L.carry(32n, xs, 0n)), 1n+mp), R.round_mod(one, h1, mp, c, hm, L.carry(32n, xs, 0n))) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
60 %Equal.sym(Nat, LV.ev(L.carry(32n, xs, 0n)), Nat.add(0n, LV.ev(xs)), LV.carry_v(32n, xs, 0n)) : {Nat.mod(_, 1n+mp) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
61 {==}
62
63
64
65def red4_x4(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>, +xs: List<&2, Nat>, +hb1: {Nat.is_le(Nat.mul(1n+LV.ev(c), LV.ev(c)), Nat.mul(4n, C.shift(256n, one))) == True{} : Bool}, +hb2: {Nat.is_le(Nat.add(Nat.mul(5n, LV.ev(c)), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {Nat.is_lt(LV.ev(L.rounds(4n, c, L.carry(32n, xs, 0n))), C.shift(256n, one)) == True{} : Bool}:
66 +t = C.shift(256n, one)
67 +cv = LV.ev(c)
68 +x0 = L.carry(32n, xs, 0n)
69 +x1 = L.carry(32n, L.fold(c, x0), 0n)
70 +x2 = L.carry(32n, L.fold(c, x1), 0n)
71 +x3 = L.carry(32n, L.fold(c, x2), 0n)
72 +h0 = I.lt_subst_l(LV.ev(xs), LV.ev(x0), Nat.mul(t, t), Equal.sym(Nat, LV.ev(x0), LV.ev(xs), LV.carry_v(32n, xs, 0n)), hx)
73 +h1b = R.round_lt1(one, h1, c, x0, t, x0_lo(one, h1, xs), h0)
74 +h1c = I.lt_subst_r(LV.ev(x1), Nat.add(t, Nat.mul(t, cv)), Nat.mul(1n+cv, t), addmul(t, cv), h1b)
75 +h2b = R.round_lt1(one, h1, c, x1, 1n+cv, R.round_lo(one, h1, L.fold(c, x0)), h1c)
76 +h2c = N.lt_le_trans(LV.ev(x2), Nat.add(t, Nat.mul(1n+cv, cv)), Nat.add(t, Nat.mul(4n, t)), h2b, N.le_add_left(Nat.mul(1n+cv, cv), Nat.mul(4n, t), t, hb1))
77 +h3b = R.round_lt1(one, h1, c, x2, 5n, R.round_lo(one, h1, L.fold(c, x1)), h2c)
78 +h4 = R.fold_lt2(one, h1, c, x3, Nat.mul(5n, cv), hb2, R.round_lo(one, h1, L.fold(c, x2)), h3b)
79 %Equal.sym(Nat, LV.ev(L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n)), 0n)), LV.ev(L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n))), R.round_v(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n))) : {Nat.is_lt(_, C.shift(256n, one)) == True{} : Bool}
80 h4
81
82
83
84def red_fin_v(+one: Nat, +h1: {one == 1n : Nat}, +mp: Nat, +c: List<&2, Nat>, +hm: {Nat.add(1n+mp, LV.ev(c)) == C.shift(256n, one) : Nat}, +hcc: {Nat.is_lt(Nat.add(LV.ev(c), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +r: List<&2, Nat>, +hlo: {FS.limbs16(one, 16n, L.take(16n, r)) == True{} : Bool}, +hr: {Nat.is_lt(LV.ev(r), C.shift(256n, one)) == True{} : Bool}) -> {LV.ev(L.canon(c, L.take(16n, r))) == Nat.mod(LV.ev(r), 1n+mp) : Nat}:
85 +et = R.take_small(one, h1, r, hr)
86 +hv = I.lt_subst_l(LV.ev(r), LV.ev(L.take(16n, r)), C.shift(256n, one), Equal.sym(Nat, LV.ev(L.take(16n, r)), LV.ev(r), et), hr)
87 %Equal.sym(Nat, LV.ev(L.canon(c, L.take(16n, r))), Nat.mod(LV.ev(L.take(16n, r)), 1n+mp), R.canon_v(one, h1, mp, c, L.take(16n, r), hlo, hv, hm, hcc)) : {_ == Nat.mod(LV.ev(r), 1n+mp) : Nat}
88 %Equal.sym(Nat, LV.ev(L.take(16n, r)), LV.ev(r), et) : {Nat.mod(_, 1n+mp) == Nat.mod(LV.ev(r), 1n+mp) : Nat}
89 {==}
90
91def red_fin_l(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>, +hcc: {Nat.is_lt(Nat.add(LV.ev(c), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +r: List<&2, Nat>, +hlo: {FS.limbs16(one, 16n, L.take(16n, r)) == True{} : Bool}, +hr: {Nat.is_lt(LV.ev(r), C.shift(256n, one)) == True{} : Bool}) -> {FS.limbs16(one, 16n, L.canon(c, L.take(16n, r))) == True{} : Bool}:
92 +et = R.take_small(one, h1, r, hr)
93 +hv = I.lt_subst_l(LV.ev(r), LV.ev(L.take(16n, r)), C.shift(256n, one), Equal.sym(Nat, LV.ev(L.take(16n, r)), LV.ev(r), et), hr)
94 R.canon_limbs(one, h1, c, L.take(16n, r), hlo, hv, hcc)
95
96def r3_lo(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>, +xs: List<&2, Nat>) -> {FS.limbs16(one, 16n, L.take(16n, L.rounds(3n, c, L.carry(32n, xs, 0n)))) == True{} : Bool}:
97 R.round_lo(one, h1, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)))
98
99def r4_lo(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>, +xs: List<&2, Nat>) -> {FS.limbs16(one, 16n, L.take(16n, L.rounds(4n, c, L.carry(32n, xs, 0n)))) == True{} : Bool}:
100 R.round_lo(one, h1, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, L.fold(c, L.carry(32n, xs, 0n)), 0n)), 0n)), 0n)))
101
102
103def reduce3_v(+one: Nat, +h1: {one == 1n : Nat}, +mp: Nat, +c: List<&2, Nat>, +hm: {Nat.add(1n+mp, LV.ev(c)) == C.shift(256n, one) : Nat}, +hcc: {Nat.is_lt(Nat.add(LV.ev(c), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +hb: {Nat.is_le(Nat.add(Nat.mul(1n+LV.ev(c), LV.ev(c)), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +xs: List<&2, Nat>, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {LV.ev(L.reduce(c, 3n, xs)) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}:
104 %Equal.sym(List<&2, Nat>, L.reduce(c, 3n, xs), L.reduce_go(c, 3n, xs), FR.lred(c, 3n, xs)) : {LV.ev(_) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
105 +r = L.rounds(3n, c, L.carry(32n, xs, 0n))
106 %Equal.sym(Nat, LV.ev(L.canon(c, L.take(16n, L.rounds(3n, c, L.carry(32n, xs, 0n))))), Nat.mod(LV.ev(L.rounds(3n, c, L.carry(32n, xs, 0n))), 1n+mp), red_fin_v(one, h1, mp, c, hm, hcc, L.rounds(3n, c, L.carry(32n, xs, 0n)), r3_lo(one, h1, c, xs), red3_x3(one, h1, c, xs, hb, hx))) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
107 %Equal.sym(Nat, Nat.mod(LV.ev(L.rounds(3n, c, L.carry(32n, xs, 0n))), 1n+mp), Nat.mod(LV.ev(xs), 1n+mp), red3_mod(one, h1, mp, c, hm, xs)) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
108 {==}
109
110def reduce3_l(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>, +hcc: {Nat.is_lt(Nat.add(LV.ev(c), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +hb: {Nat.is_le(Nat.add(Nat.mul(1n+LV.ev(c), LV.ev(c)), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +xs: List<&2, Nat>, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {FS.limbs16(one, 16n, L.reduce(c, 3n, xs)) == True{} : Bool}:
111 %Equal.sym(List<&2, Nat>, L.reduce(c, 3n, xs), L.reduce_go(c, 3n, xs), FR.lred(c, 3n, xs)) : {FS.limbs16(one, 16n, _) == True{} : Bool}
112 red_fin_l(one, h1, c, hcc, L.rounds(3n, c, L.carry(32n, xs, 0n)), r3_lo(one, h1, c, xs), red3_x3(one, h1, c, xs, hb, hx))
113
114def reduce4_v(+one: Nat, +h1: {one == 1n : Nat}, +mp: Nat, +c: List<&2, Nat>, +hm: {Nat.add(1n+mp, LV.ev(c)) == C.shift(256n, one) : Nat}, +hcc: {Nat.is_lt(Nat.add(LV.ev(c), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +hb1: {Nat.is_le(Nat.mul(1n+LV.ev(c), LV.ev(c)), Nat.mul(4n, C.shift(256n, one))) == True{} : Bool}, +hb2: {Nat.is_le(Nat.add(Nat.mul(5n, LV.ev(c)), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +xs: List<&2, Nat>, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {LV.ev(L.reduce(c, 4n, xs)) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}:
115 %Equal.sym(List<&2, Nat>, L.reduce(c, 4n, xs), L.reduce_go(c, 4n, xs), FR.lred(c, 4n, xs)) : {LV.ev(_) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
116 %Equal.sym(Nat, LV.ev(L.canon(c, L.take(16n, L.rounds(4n, c, L.carry(32n, xs, 0n))))), Nat.mod(LV.ev(L.rounds(4n, c, L.carry(32n, xs, 0n))), 1n+mp), red_fin_v(one, h1, mp, c, hm, hcc, L.rounds(4n, c, L.carry(32n, xs, 0n)), r4_lo(one, h1, c, xs), red4_x4(one, h1, c, xs, hb1, hb2, hx))) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
117 %Equal.sym(Nat, Nat.mod(LV.ev(L.rounds(4n, c, L.carry(32n, xs, 0n))), 1n+mp), Nat.mod(LV.ev(xs), 1n+mp), red4_mod(one, h1, mp, c, hm, xs)) : {_ == Nat.mod(LV.ev(xs), 1n+mp) : Nat}
118 {==}
119
120def reduce4_l(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>, +hcc: {Nat.is_lt(Nat.add(LV.ev(c), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +hb1: {Nat.is_le(Nat.mul(1n+LV.ev(c), LV.ev(c)), Nat.mul(4n, C.shift(256n, one))) == True{} : Bool}, +hb2: {Nat.is_le(Nat.add(Nat.mul(5n, LV.ev(c)), LV.ev(c)), C.shift(256n, one)) == True{} : Bool}, +xs: List<&2, Nat>, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {FS.limbs16(one, 16n, L.reduce(c, 4n, xs)) == True{} : Bool}:
121 %Equal.sym(List<&2, Nat>, L.reduce(c, 4n, xs), L.reduce_go(c, 4n, xs), FR.lred(c, 4n, xs)) : {FS.limbs16(one, 16n, _) == True{} : Bool}
122 red_fin_l(one, h1, c, hcc, L.rounds(4n, c, L.carry(32n, xs, 0n)), r4_lo(one, h1, c, xs), red4_x4(one, h1, c, xs, hb1, hb2, hx))
123
124
125
126def hv_ev(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>) -> {FS.value(one, c) == LV.ev(c) : Nat}:
127 LV.ev_value(one, h1, c)
128
129def reduce3_vv(+one: Nat, +h1: {one == 1n : Nat}, +mp: Nat, +c: List<&2, Nat>, +hm: {Nat.add(1n+mp, FS.value(one, c)) == C.shift(256n, one) : Nat}, +hcc: {Nat.is_lt(Nat.add(FS.value(one, c), FS.value(one, c)), C.shift(256n, one)) == True{} : Bool}, +hb: {Nat.is_le(Nat.add(Nat.mul(1n+FS.value(one, c), FS.value(one, c)), FS.value(one, c)), C.shift(256n, one)) == True{} : Bool}, +xs: List<&2, Nat>, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {LV.ev(L.reduce(c, 3n, xs)) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}:
130 +e = hv_ev(one, h1, c)
131 +hm2 = Lg.subst(Nat, z => {Nat.add(1n+mp, z) == C.shift(256n, one) : Nat}, FS.value(one, c), LV.ev(c), e, hm)
132 +hcc2 = Lg.subst(Nat, z => {Nat.is_lt(Nat.add(z, z), C.shift(256n, one)) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hcc)
133 +hb2 = Lg.subst(Nat, z => {Nat.is_le(Nat.add(Nat.mul(1n+z, z), z), C.shift(256n, one)) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hb)
134 reduce3_v(one, h1, mp, c, hm2, hcc2, hb2, xs, hx)
135
136def reduce3_lv(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>, +hcc: {Nat.is_lt(Nat.add(FS.value(one, c), FS.value(one, c)), C.shift(256n, one)) == True{} : Bool}, +hb: {Nat.is_le(Nat.add(Nat.mul(1n+FS.value(one, c), FS.value(one, c)), FS.value(one, c)), C.shift(256n, one)) == True{} : Bool}, +xs: List<&2, Nat>, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {FS.limbs16(one, 16n, L.reduce(c, 3n, xs)) == True{} : Bool}:
137 +e = hv_ev(one, h1, c)
138 +hcc2 = Lg.subst(Nat, z => {Nat.is_lt(Nat.add(z, z), C.shift(256n, one)) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hcc)
139 +hb2 = Lg.subst(Nat, z => {Nat.is_le(Nat.add(Nat.mul(1n+z, z), z), C.shift(256n, one)) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hb)
140 reduce3_l(one, h1, c, hcc2, hb2, xs, hx)
141
142def reduce4_vv(+one: Nat, +h1: {one == 1n : Nat}, +mp: Nat, +c: List<&2, Nat>, +hm: {Nat.add(1n+mp, FS.value(one, c)) == C.shift(256n, one) : Nat}, +hcc: {Nat.is_lt(Nat.add(FS.value(one, c), FS.value(one, c)), C.shift(256n, one)) == True{} : Bool}, +hb1: {Nat.is_le(Nat.mul(1n+FS.value(one, c), FS.value(one, c)), Nat.mul(4n, C.shift(256n, one))) == True{} : Bool}, +hb2: {Nat.is_le(Nat.add(Nat.mul(5n, FS.value(one, c)), FS.value(one, c)), C.shift(256n, one)) == True{} : Bool}, +xs: List<&2, Nat>, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {LV.ev(L.reduce(c, 4n, xs)) == Nat.mod(LV.ev(xs), 1n+mp) : Nat}:
143 +e = hv_ev(one, h1, c)
144 +hm2 = Lg.subst(Nat, z => {Nat.add(1n+mp, z) == C.shift(256n, one) : Nat}, FS.value(one, c), LV.ev(c), e, hm)
145 +hcc2 = Lg.subst(Nat, z => {Nat.is_lt(Nat.add(z, z), C.shift(256n, one)) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hcc)
146 +hb12 = Lg.subst(Nat, z => {Nat.is_le(Nat.mul(1n+z, z), Nat.mul(4n, C.shift(256n, one))) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hb1)
147 +hb22 = Lg.subst(Nat, z => {Nat.is_le(Nat.add(Nat.mul(5n, z), z), C.shift(256n, one)) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hb2)
148 reduce4_v(one, h1, mp, c, hm2, hcc2, hb12, hb22, xs, hx)
149
150def reduce4_lv(+one: Nat, +h1: {one == 1n : Nat}, +c: List<&2, Nat>, +hcc: {Nat.is_lt(Nat.add(FS.value(one, c), FS.value(one, c)), C.shift(256n, one)) == True{} : Bool}, +hb1: {Nat.is_le(Nat.mul(1n+FS.value(one, c), FS.value(one, c)), Nat.mul(4n, C.shift(256n, one))) == True{} : Bool}, +hb2: {Nat.is_le(Nat.add(Nat.mul(5n, FS.value(one, c)), FS.value(one, c)), C.shift(256n, one)) == True{} : Bool}, +xs: List<&2, Nat>, +hx: {Nat.is_lt(LV.ev(xs), Nat.mul(C.shift(256n, one), C.shift(256n, one))) == True{} : Bool}) -> {FS.limbs16(one, 16n, L.reduce(c, 4n, xs)) == True{} : Bool}:
151 +e = hv_ev(one, h1, c)
152 +hcc2 = Lg.subst(Nat, z => {Nat.is_lt(Nat.add(z, z), C.shift(256n, one)) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hcc)
153 +hb12 = Lg.subst(Nat, z => {Nat.is_le(Nat.mul(1n+z, z), Nat.mul(4n, C.shift(256n, one))) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hb1)
154 +hb22 = Lg.subst(Nat, z => {Nat.is_le(Nat.add(Nat.mul(5n, z), z), C.shift(256n, one)) == True{} : Bool}, FS.value(one, c), LV.ev(c), e, hb2)
155 reduce4_l(one, h1, c, hcc2, hb12, hb22, xs, hx)