Skip to content

Commit e4fa1b7

Browse files
dtumadtamirhemo
andauthored
feat: merge release branch (#88)
* feat: release branch * new files * extra comments * add comment --------- Co-authored-by: Tamir Hemo <[email protected]>
1 parent af625bf commit e4fa1b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+3788
-2107
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Each chip contains:
5050
For each RISC-V instruction, we prove that:
5151

5252
1. **The constraints are satisfiable**: When the instruction executes correctly, there exists an assignment to the constraint variables
53-
2. **The constraints are sound**: Any satisfying assignment corresponds to a valid RISC-V execution
53+
2. **The constraints are sound**: Any satisfying assignment corresponds to a valid RISC-V execution.
5454

5555
The proofs connect two representations:
5656
- **RISC-V Semantics**: Formal specification from the Sail RISC-V model
@@ -72,6 +72,11 @@ theorem correct_add
7272

7373
This theorem states that when all constraints hold, the SP1 add operation produces the same result as the RISC-V specification.
7474

75+
## Constraints
76+
Constraints come from two sources:
77+
- Constraints implied by the lookup argument.
78+
- Constraints implied by the equations.
79+
7580
## Building
7681

7782
### Prerequisites

SP1Chips.lean

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ import SP1Chips.Addw.Constraints
66
import SP1Chips.AddwChip
77
import SP1Chips.Bitwise.Constraints
88
import SP1Chips.BitwiseChip
9-
-- import SP1Chips.Branch.BEQ
10-
-- import SP1Chips.Branch.BGE
11-
-- import SP1Chips.Branch.BGEU
12-
-- import SP1Chips.Branch.BLT
13-
-- import SP1Chips.Branch.BLTU
14-
-- import SP1Chips.Branch.BNE
159
import SP1Chips.Branch.Constraints
1610
import SP1Chips.BranchChip
1711
import SP1Chips.DivRem.Constraints

SP1Chips/AddChip.lean

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,76 @@
1-
import SP1Foundations
2-
import SP1Operations.Operation.AddOperation
3-
import SP1Operations.Reader.CPUState
4-
import SP1Operations.Reader.RTypeReader
5-
import LeanRV64D.RiscvInstsEnd
6-
71
import SP1Chips.Add.Constraints
82

9-
open LeanRV64D.Functions BitVec
3+
open LeanRV64D.Functions
104

115
namespace Add
126

13-
variable
14-
(Main : Vector (Fin KB) 34)
15-
(s : SailState)
16-
(cstrs : (constraints Main).allHold)
17-
(h_is_real : Main[33] = 1)
18-
19-
noncomputable def spec_add (rs2 rs1 rd : regidx) : SailM Unit := do
20-
Sail.writeReg Register.nextPC ((← Sail.readReg Register.PC) + 4#64)
21-
_ ← execute_RTYPE rs2 rs1 rd rop.ADD
22-
pure ()
7+
variable (Main : Vector (Fin KB) 34)
238

9+
-- The input and output values in the SP1 implementation
2410
def sp1_op_a : BitVec 5 := BitVec.ofNat 5 Main[6]
25-
2611
def sp1_op_b : BitVec 5 := BitVec.ofNat 5 Main[14]
27-
2812
def sp1_op_c : BitVec 5 := BitVec.ofNat 5 Main[21]
2913

30-
def sp1_add : SailM Unit := do
31-
let op_a := sp1_op_a Main
14+
/-- Specification of the ADD operation in sail, while setting the next program counter-/
15+
def spec_add (rs2 rs1 rd : regidx) : SailM ExecutionResult := do
16+
Sail.writeReg Register.nextPC ((← Sail.readReg Register.PC) + 4#64)
17+
execute_RTYPE rs2 rs1 rd rop.ADD
18+
19+
/-- Behavior of the ADD operation in SP1, writing the given values to registers-/
20+
def sp1_add : SailM ExecutionResult := do
3221
Sail.writeReg Register.nextPC (Word.toBitVec64 #v[Main[3] + 4, Main[4], Main[5], 0])
33-
Sail.write_reg op_a (Word.toBitVec64 #v[Main[29], Main[30], Main[31], Main[32]])
22+
Sail.write_reg (sp1_op_a Main) (Word.toBitVec64 #v[Main[29], Main[30], Main[31], Main[32]])
23+
return RETIRE_SUCCESS
3424

3525
open Sail
3626

37-
set_option pp.parens true in
27+
/-- Given that all the constraints hold for the input `Main`, `s` is a machine state with
28+
registers initialized to appropriate values, and the column is a real column,
29+
the Sail spec and SP1 implementation behave the same. -/
3830
theorem correct_add
39-
(Main : Vector (Fin KB) 34)
40-
(s : SailState)
41-
(cstrs : (constraints Main).allHold)
42-
(h_is_real : Main[33] = 1)
43-
(state_cstrs : (constraints Main).initialState s) :
44-
let op_c := sp1_op_c Main
45-
let op_b := sp1_op_b Main
46-
let op_a := sp1_op_a Main
47-
(spec_add (.Regidx op_c) (.Regidx op_b) (.Regidx op_a)).run s = (sp1_add Main).run s
48-
:= by
49-
simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp, List.Forall, AddOperation.constraints, CPUState.constraints, RTypeReader.constraints] at state_cstrs
50-
obtain ⟨read_pc, trusted_instr_state, _, read_op_b, read_op_c⟩ := state_cstrs
51-
simp [constraints] at cstrs
52-
obtain ⟨add_op_cstrs, cpu_cstrs, reader_cstrs, rest⟩ := cstrs
53-
rw [CPUState.allHold_constraints_iff_is_real h_is_real] at cpu_cstrs
54-
rw [RTypeReader.allHold_constraints_iff_is_real h_is_real] at reader_cstrs
55-
simp [Opcode.ofNat, Nat.ble] at reader_cstrs
56-
obtain ⟨ trusted_instr_prop, _, _, _, _, _, _, _, ⟨ ⟨ _, _, ⟨ _, is_U64_b, is_U64_c ⟩ ⟩, _ ⟩⟩ := reader_cstrs
57-
simp [Opcode.ofNat, Nat.ble] at trusted_instr_state trusted_instr_prop
31+
(Main : Vector (Fin KB) 34)
32+
(s : SailState)
33+
(h_cstrs : (constraints Main).allHold)
34+
(h_is_real : Main[33] = 1)
35+
(state_cstrs : (constraints Main).initialState s) :
36+
let op_c := .Regidx (sp1_op_c Main)
37+
let op_b := .Regidx (sp1_op_b Main)
38+
let op_a := .Regidx (sp1_op_a Main)
39+
(spec_add op_c op_b op_a).run s = (sp1_add Main).run s := by
40+
-- Simplify the main constraints and split them into parts
41+
simp [constraints] at h_cstrs
42+
obtain ⟨add_op_cstrs, cpu_cstrs, reader_cstrs, rest⟩ := h_cstrs
43+
rw [CPUState.allHold_constraints_iff_is_real h_is_real] at cpu_cstrs
44+
rw [RTypeReader.allHold_constraints_iff_is_real h_is_real] at reader_cstrs
45+
simp [Opcode.ofNat, Nat.ble] at reader_cstrs
5846

59-
rw [h_is_real] at *
60-
apply AddOperation.spec is_U64_b is_U64_c at add_op_cstrs
61-
obtain ⟨ is_U64_val, is_add ⟩ := add_op_cstrs
62-
simp [BitVec.ofNatLT_eq_ofNat] at *
47+
-- Show the write values are all register values (i.e. are 5-bit)
48+
have h6 : Main[6] < 32 := by aesop
49+
have h14 : Main[14] < 32 := by aesop
50+
have h21 : Main[21] < 32 := by aesop
6351

64-
-- Now the monadic manipulation
65-
simp [spec_add, sp1_add, execute, execute_RTYPE']
66-
rw [run_readReg, read_pc]
67-
simp [sp1_op_b, read_op_b (by omega)]
68-
simp [sp1_op_c, read_op_c (by omega)]
69-
simp [sp1_op_a]
70-
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
52+
-- Extract constraints about the initial register states
53+
simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp,
54+
List.Forall, AddOperation.constraints, CPUState.constraints, BitVec.ofNatLT_eq_ofNat,
55+
RTypeReader.constraints, h6, h14, h21, h_is_real] at state_cstrs
56+
obtain ⟨read_pc, read_op_a, read_op_b, read_op_c⟩ := state_cstrs
57+
58+
rw [h_is_real] at *
59+
apply AddOperation.spec (by aesop) (by aesop) at add_op_cstrs
7160

72-
by_cases h_is_op_a_0 : Main[6] = 0 <;> simp_all
73-
. rw [← is_add]
74-
simp [Word.toBitVec64, Word.toNat]
75-
. rw [if_neg (by simp [← BitVec.toNat_inj]; omega)]
76-
rw [if_neg (by simp [← BitVec.toNat_inj]; omega)]
77-
simp [Word.toBitVec64, Word.toNat]
78-
rfl
61+
-- Simplify the monadic operations
62+
simp [spec_add, sp1_add, execute, execute_RTYPE']
63+
rw [run_readReg, read_pc]
64+
simp [sp1_op_b, read_op_b, sp1_op_c, read_op_c, sp1_op_a]
65+
66+
-- Simplify the expressions using the arithmetic constraints
67+
by_cases h_is_op_a_0 : Main[6] = 0 <;> simp_all
68+
. rw [← add_op_cstrs.2]
69+
simp [Word.toBitVec64, Word.toNat]
70+
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
71+
. rw [if_neg (by simp [← BitVec.toNat_inj]; omega), if_neg (by simp [← BitVec.toNat_inj]; omega)]
72+
simp [execute_RTYPE_pure, bitVecToRegidxVal, Word.toBitVec64, Word.toNat]
73+
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
74+
simp
7975

8076
end Add

SP1Chips/AddiChip.lean

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,23 @@ theorem correct_addi
4141
(spec_addi op_c (.Regidx op_b) (.Regidx op_a)).run s = (sp1_addi Main).run s
4242
:= by
4343
-- Obtain and simplify state and pure constraints
44-
simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp, List.Forall, AddOperation.constraints, CPUState.constraints, ITypeReader.constraints, h_is_real] at state_cstrs
45-
obtain ⟨read_pc, trusted_instr_state, read_op_b, read_op_c⟩ := state_cstrs
4644
simp [constraints] at cstrs
4745
obtain ⟨add_op_cstrs, cpu_cstrs, reader_cstrs, rest⟩ := cstrs
4846
rw [CPUState.allHold_constraints_iff_is_real h_is_real] at cpu_cstrs
4947
rw [ITypeReader.allHold_constraints_iff_is_real h_is_real] at reader_cstrs
48+
simp [Opcode.ofNat, Nat.ble] at reader_cstrs
5049

5150
obtain ⟨ _, trusted_instr_prop, hcm1, hcm2, c0, c1, c2, c3, h11, h12, h13, h14, h15, h16, h17, h18, h19, h20, ⟨ is_U64_a, is_U64_b, hu64 ⟩⟩ := reader_cstrs
5251

52+
have h6 : Main[6] < 32 := by aesop
53+
have h14 : Main[14] < 32 := by aesop
54+
55+
simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp,
56+
List.Forall, AddOperation.constraints, CPUState.constraints, ITypeReader.constraints,
57+
h6, h14, h_is_real] at state_cstrs
58+
59+
obtain ⟨read_pc, read_op_b, read_op_c⟩ := state_cstrs
60+
5361
simp_all [Opcode.ofNat, Nat.ble]
5462
have is_U64_c : Word.isU64 #v[Main[21], Main[22], Main[23], Main[24]]
5563
:= by apply Word.isU64_of_cases c0 c1 c2 c3
@@ -65,18 +73,21 @@ theorem correct_addi
6573
simp [sp1_op_b, read_op_b]
6674
simp [sp1_op_c, read_op_c]
6775
simp [sp1_op_a]
68-
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
76+
6977

7078
by_cases h_is_op_a_0 : Main[6] = 0
7179
. have : Main[13] = 1 := by clear *- h12 h_is_op_a_0; aesop
7280
rw [← is_add] at *
7381
simp [Word.toBitVec64, Word.toNat, h_is_op_a_0]
82+
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
7483
clear *- this hu64
7584
aesop
7685
. rw [if_neg (by simp [← BitVec.toNat_inj]; omega)]
7786
rw [if_neg (by simp [← BitVec.toNat_inj]; omega)]
78-
rw [is_add, trusted_instr_prop.2]
87+
rw [is_add, trusted_instr_prop]
7988
simp [Word.toBitVec64, Word.toNat]
89+
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
90+
simp
8091
rfl
8192

8293
end Addi

SP1Chips/AddwChip.lean

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,18 @@ theorem correct_addw
4343
let op_a := sp1_op_a Main
4444
(spec_addw (.Regidx op_c) (.Regidx op_b) (.Regidx op_a)).run s = (sp1_addw Main).run s
4545
:= by
46-
simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp, List.Forall,
47-
AddwOperation.constraints, CPUState.constraints, ALUTypeReader.constraints, U16MSBOperation.constraints,
48-
h_is_real, h_is_trusted] at state_cstrs
49-
obtain ⟨read_pc, trusted_instr_state, read_op_a, read_op_b, read_op_c⟩ := state_cstrs
5046
simp [constraints] at cstrs
5147

5248
obtain ⟨addw_op_cstrs, cpu_cstrs, alu_cstrs, _⟩ := cstrs
5349
rw [CPUState.allHold_constraints_iff_is_real h_is_real] at cpu_cstrs
5450
rw [ALUTypeReader.allHold_constraints_iff_is_real h_is_real] at alu_cstrs
5551
obtain ⟨ _, trusted_instr_prop, _, _, _, _, _, _, _, _, _, _, _, _, _, _, is_U64_a, is_U64_b, is_U64_c , _, _ ⟩ := alu_cstrs
52+
53+
simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp, List.Forall,
54+
AddwOperation.constraints, CPUState.constraints, ALUTypeReader.constraints, U16MSBOperation.constraints,
55+
h_is_real, h_is_trusted] at state_cstrs
56+
obtain ⟨read_pc, read_op_a, read_op_b, read_op_c⟩ := state_cstrs
57+
5658
simp [Opcode.ofNat, Nat.ble] at *
5759
simp_all
5860

@@ -73,16 +75,18 @@ theorem correct_addw
7375
rw [exec_RTYPEW_pure_bv_to_w _ _ _ (by omega) (by omega)]
7476
simp [execute_RTYPEW_pure_w]
7577
rw [← is_addw] at is_msb
76-
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
7778

7879
by_cases h_is_op_a_0 : Main[6] = 0 <;> simp_all
7980
. simp [Word.toBitVec64, Word.toNat]
81+
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
8082
. have : BitVec.ofNat 5 Main[6] ≠ 0#5 := by
8183
simp [← BitVec.toNat_inj]; omega
8284
simp [this, Word.toBitVec64, Word.toNat]
83-
rw [← is_addw]; congr
85+
rw [← is_addw]
8486
rw [HWord.sign_extend_32_to_64_msb is_U32_val]
8587
simp [Word.toBitVec64, Word.toNat]
88+
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
89+
simp [bitVecToRegidxVal]
8690

8791
end Addw
8892

@@ -124,14 +128,15 @@ theorem correct_addw
124128
let op_a := sp1_op_a Main
125129
(spec_addiw op_c (.Regidx op_b) (.Regidx op_a)).run s = (sp1_addiw Main).run s
126130
:= by
127-
-- Obtain and simplify state and pure constraints
128-
simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp, List.Forall, AddwOperation.constraints, CPUState.constraints, ALUTypeReader.constraints, U16MSBOperation.constraints, h_is_real] at state_cstrs
129-
obtain ⟨read_pc, trusted_instr_state, read_op_a, read_op_b, read_op_c⟩ := state_cstrs
130131
simp [constraints] at cstrs
131132
obtain ⟨addw_op_cstrs, cpu_cstrs, alu_cstrs, _ ⟩ := cstrs
132133
rw [CPUState.allHold_constraints_iff_is_real h_is_real] at cpu_cstrs
133134
rw [ALUTypeReader.allHold_constraints_iff_is_real h_is_real] at alu_cstrs
134135
obtain ⟨ _, trusted_instr_prop, _, _, ⟨ c0, c1, c2, c3 ⟩, _, _, _, _, _, _, _, _, _, _, _, is_U64_a, is_U64_b, _, _, _ ⟩ := alu_cstrs
136+
137+
simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp, List.Forall, AddwOperation.constraints, CPUState.constraints, ALUTypeReader.constraints, U16MSBOperation.constraints, h_is_real] at state_cstrs
138+
obtain ⟨read_pc, read_op_a, read_op_b, read_op_c⟩ := state_cstrs
139+
135140
simp [Opcode.ofNat, Nat.ble] at *
136141
simp_all
137142
have is_U64_c : Word.isU64 #v[Main[21], Main[22], Main[23], Main[24]]
@@ -155,15 +160,17 @@ theorem correct_addw
155160
rw [exec_RTYPEW_pure_bv_to_w _ _ _ (by omega) (by omega)]
156161
simp [execute_RTYPEW_pure_w]
157162
rw [← is_addw] at is_msb
158-
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
159163

160164
by_cases h_is_op_a_0 : Main[6] = 0 <;> simp_all
161165
. simp [Word.toBitVec64, Word.toNat]
166+
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
162167
. have : BitVec.ofNat 5 Main[6] ≠ 0#5 := by
163168
simp [← BitVec.toNat_inj]; omega
164169
simp [this, Word.toBitVec64, Word.toNat]
165-
rw [← is_addw]; congr
170+
rw [← is_addw]
166171
rw [HWord.sign_extend_32_to_64_msb is_U32_val]
167172
simp [Word.toBitVec64, Word.toNat]
173+
rw [KoalaBear.add4_into_pc_ofNat (by omega)]
174+
simp [bitVecToRegidxVal]
168175

169176
end Addiw

0 commit comments

Comments
 (0)