A boot circuit has finished checking a signature. The image fails, so its result register stores 0. Before the CPU’s next fetch request, a fault changes that stored value to 1. The verifier was correct, but the release circuit reads a different answer.
Protecting the result requires more than being able to read the register. Integrity protection must expose changes within its stated scope and block the operation before the wrong value is used. Extra check bits can help, but they do not reveal every possible fault.
We compare parity, complementary encoding and error-correcting codes against the same release problem. For each scheme, identify which changes it rejects, then try changing FAIL into a still-valid PASS. A small experiment reproduces those counterexamples.
You need registers, basic logic and clock sampling. Lesson 2 explains the fault-model contract and can be consulted as needed. These are teaching circuits. The Python exercise has run; RTL simulation, synthesis, formal proof and silicon validation have not.
1. Why store more bits?
Imagine a school meal ticket with data positions and check positions. The data records permission to collect a meal; the check positions help identify specified changes. With one position, both 0 and 1 are valid. Extra positions let the school declare some patterns invalid, like data and check bits forming a codeword. A correctly formed ticket can still carry the wrong entitlement. Valid format does not establish permission to collect.
With one permission bit, both 0 and 1 are valid values. After a flip, the reader has no third value that identifies an error. Integrity encoding stores data together with extra check bits; the combined value is a codeword. DFF in the diagrams denotes a circuit that stores a bit.
The designer defines valid codewords and leaves other combinations invalid. A checker can report a fault that moves stored state into an invalid combination. If it moves into another valid codeword, format checking alone cannot reveal the change.
That is the counterexample to search for: can valid FAIL become valid PASS? A valid codeword does not establish correct authorization. Authorization also depends on this image’s policy result and how that result reaches the consumer.
An instruction fetch reads a program instruction. We use a simplified fetch interface. accepted_commit means that the downstream interface accepted the fetch. It does not represent instruction retirement in a complete CPU.
2. Define the fault target first
First target only the stored ticket: alter it after edge 3 and request collection at edges 4 and 6. The original entitlement ledger, checker, and handover desk are trusted. One mask names the positions changed by one event; the main table reports one-position, two-position, and other budgets separately. Two collections do not imply two alterations. Changing eligibility before printing or final handover permission is another target. Paper positions do not represent physical spacing on a chip.
Fault injection deliberately perturbs a circuit. A fault model specifies the allowed perturbations. First, we change only the register that stores the codeword. Each experiment has one injection event.
One event can change several bits. We test each bit count separately. These are selected model conditions. They are not measured capabilities of a physical attacker.
An edge is a clock sampling instant. Clock/reset means the clock and reset signals.
| Model field | Setting in this lesson |
|---|---|
| Protected event | An unauthorized image must receive no accepted_commit |
| Normal schedule | Reset at edge 0; capture the result at edge 2 |
| Fault timing | Flip stored bits after the normal update at edge 3 |
| Fault duration | The changed state remains; no later overwrite or automatic repair |
| Fault budget | One event, one coded register; separate groups change 1..4 bits |
| Accepting edges | Requests at edges 4 and 6; each request is valid and the receiver is ready |
| Observation window | Edges 0..7; both requests share one attempt |
| Trusted circuitry | Encoder, checker, local block, error history and completion flag |
| Other trusted elements | Image, policy, independent reference, clock/reset, handshake and accepting interface |
Each edge first samples fetch acceptance. Registers then update. The injector finally changes the new state. The fault can therefore remain until the next request.
An independent reference records the original authorization. It does not read the faulted codeword. The experiment uses it to identify unauthorized acceptance. The image is fixed and unauthorized here.
We assume that the fault affects only the target register. The checker and control logic remain untouched. A physical disturbance can affect several locations. Product validation must examine that boundary separately.
Fixing this boundary lets us compare the encodings themselves. Section 8 separately adds the source and final grant as targets to test how the conclusion changes. Those experiments do not combine their faults with the storage fault in this section.
3. Parity: one bit checks odd or even
Suppose a ticket must contain an even number of ones. 00000 has valid format but grants no meal. Changing just its data position to 00001 makes the count odd. Changing the data and saved check position together to 10001 restores an even count while granting a meal: the parity mask 0x11 counterexample. Reprinting the check mark from altered data destroys the evidence of the original stored value. Parity does not identify every two-position change.
Parity records odd or even bit count using one check bit. This lesson uses even parity: a valid codeword contains an even number of ones. Notice what it checks: parity, not the original value of every bit.
We store four data bits and one parity bit. Data 0000 means FAIL. Data 0001 means PASS. All other data values must block the fetch.
Starting from FAIL, 00000, one flip makes the number of ones odd and triggers an error. One extra check bit therefore exposes any single stored-bit flip. It does not locate the faulty bit.
Two flips can preserve parity. Changing the lowest data bit and the parity bit together turns 00000 into 10001, the valid PASS codeword. No parity error appears. Detecting a single-bit fault does not establish protection against this two-bit counterexample.
XOR means exclusive OR. It can calculate whether the number of ones is odd or even. Verilog’s ^data_q reduces the whole vector. The check below does not modify stored state.
AND requires all conditions to be true together. NOT exchanges 0 and 1. The diagrams use these names for logic blocks.
// Store the check bit when the trusted result is written.
if (write_en) begin
data_q <= data_i;
parity_q <= ^data_i;
end
assign local_bad = (^data_q) ^ parity_q;
assign decoded_pass = (data_q == 4'b0001);
Store the data and its check bit together. Recreating parity from faulted data makes the values agree again. That wiring cannot check a change to the previously stored value.
For complementary encoding, ask the same two questions: which flips produce an invalid value, and which produce valid PASS? Changing the storage scheme does not remove either question.
4. Complementary encoding: store opposite values
Use a two-position ticket: 01 means refused, 10 means allowed, and the positions must be opposite. Changing one produces 00 or 11, which can be rejected. Changing both produces another valid ticket. This represents stored complementary bits. Copying and inverting one live position at the desk provides no second stored evidence: the copy follows its alteration. Two positions do not mean two independent eligibility checks.
Complementary encoding stores one decision in two opposite bits. We use 01 for FAIL and 10 for PASS; 00 and 11 are invalid. The reader checks that the pair remains complementary and then compares the full PASS codeword.
One flip from 01 produces 00 or 11, both rejected. Two flips produce 10. The stored pair is still complementary, but its authorization meaning is wrong. Checking the relationship between bits and checking the authorization source are separate jobs.
Inverting the same Q on the read path does not add a stored copy. Q is a register’s output. If a fault changes Q, the inverted wire changes too. Those wires cannot provide the same storage check.
Both registers can also share one source. A wrong source can produce a valid wrong codeword. The complementary relationship cannot establish correct source authorization.
The encoding improves detection of specified storage changes; it does not perform two independent signature checks. A claim of independent protection paths also needs source, clock, reset and post-synthesis analysis.
5. SECDED: why can correction release a wrong value?
Now use an eight-position ticket with a fixed repair rule for patterns that look like one printing error. Three changes turn 00000000 into 00000111. The rule classifies it as correctable and changes position 8, producing meal-authorizing 10000111, or 0x87. This is the lesson’s SECDED miscorrection. CE is the decoder’s classification, not eyewitness evidence of how many positions changed. A one-error correction rule does not repair every ticket to its original entitlement.
The preceding schemes reject detected errors without repairing the data. An error-correcting code adds enough check information to recover the original value within a specified error range. Here ECC means Error-correcting Code, not elliptic-curve cryptography.
SECDED means single-error correction and double-error detection. Its scope matters: “corrects one bit” does not mean “repairs every fault.” Outside that range, the decoder can classify a fault incorrectly.
We use a custom extended Hamming (8,4) code. It stores four data bits in eight bits. Start with two values: FAIL is 0x00, and PASS is 0x87. The prefix 0x denotes hexadecimal.
The decoder uses the syndrome and overall parity to produce CE and UE. CE means it classifies the error as correctable; UE means it classifies it as uncorrectable. It sees the current codeword, not the attack’s history. CE does not prove that only one bit actually changed.
Changing three bits from 0x00 to 0x07 produces check results matching a single-bit error classification. The decoder sets CE and flips position 8, producing PASS at 0x87. This is one specified miscorrection pattern, not a claim that every three-bit pattern behaves identically. The expandable explanation below gives the layout.
Now compare two use policies. Correct and continue selects the corrected value. It rejects only UE. The CE counterexample therefore causes unauthorized acceptance.
Reject on error rejects CE and UE. Its grant decision also uses no corrected value. It blocks this three-bit counterexample. However, four particular flips can still form a valid PASS codeword.
The policies differ in whether they trust the corrected value after an error. Continuing can improve availability but requires justification for the assumed fault range. Rejection is more conservative and can also stop authorized work. Section 7 records unauthorized acceptance and blocked authorized requests separately.
Why does 0x07 set CE? Expand the bit layout.
Positions 1..8 correspond to stored bits 0..7. Data occupies positions 3, 5, 6 and 7. Check bits occupy positions 1, 2, 4 and 8.
| Position | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| Role | p1 | p2 | d0 | p4 | d1 | d2 | d3 | p8 |
S is the syndrome, an index formed from three check results. P is parity across all eight bits. The download contains the complete calculation.
| S | P | Decoder action |
|---|---|---|
| 0 | 0 | No CE or UE flag |
| 0 | 1 | Set CE; flip position 8 |
| Nonzero | 1 | Set CE; flip position S |
| Nonzero | 0 | Set UE; do not perform single-bit correction |
Mask 0x07 flips positions 1, 2 and 3. Their check indices cancel, so S is 0 and P is 1. The decoder flips position 8. The binary display of 0x87 is 10000111. This display runs from bit 7 to bit 0.
Different valid codewords differ in at least four bits. This is a minimum code distance of four. Distance describes separation between raw codewords. Acceptance after correction still needs separate analysis.
OpenTitan’s OTBN uses a different code. It uses a (39,32) Hsiao code for integrity checks, without automatic correction. The original design discussion also identifies multi-bit miscorrection risks. We use it to explain policy choices. We do not reproduce the OTBN codec. OTBN design, original OpenTitan discussion
Calculate the SECDED miscorrection without the figure
The checker receives only the current eight positions. With S=0 and P=1, the table instructs it to flip position 8. It does not know that positions 1, 2, and 3 changed from the original 0x00. Continuing after correction and rejecting CE therefore produce different collection decisions. Syndrome groups checks; it does not reconstruct the attack history. A directly substituted valid 0x87 can avoid a format error under either policy.
Write the syndrome checks as s1, s2 and s4. s1 checks positions 1,3,5,7; s2 checks 2,3,6,7; s4 checks 4,5,6,7. XOR each group, then form S=s1+2×s2+4×s4. P XORs all eight bits. The addition assembles an index; it is not another parity calculation.
For 0x07, only positions 1,2,3 are one. Thus s1=1 XOR 1=0, s2=1 XOR 1=0 and s4=0, giving S=0. Three ones give P=1. The decoder sees only (S,P)=(0,1). It follows the table and flips position 8: 00000111 XOR 10000000 = 10000111, or 0x87. Data bit d0 at position 3 is one; the other data bits are zero. Decoded data is 0001, meaning pass.
“Correct and continue” sees CE=1 and UE=0 and uses 0001. “Reject on error” also gates acceptance with CE and rejects this attempt. But directly flipping four bits to 0x87 yields S=P=0: neither policy detects a format error. This calculation separates code distance, decoder classification and permission policy. Its target is specified storage bits; it does not establish protection of the source or final grant.
6. When must the circuit block an error?
At edge 4 the desk already sees an invalid meal ticket, but its incident log updates only after that bell. Consulting just the old log can release the first meal. Current rejection corresponds to local_bad; retained incident history corresponds to sticky. Using both protects the specified schedule. The story assumes the current check arrives before handover; it does not establish physical propagation time or protection from intra-cycle glitches.
After detecting an error, decide when to block. local_bad is the current check result; err_sticky_q records error history. Their timing differs. Saying “error handling exists” leaves that distinction unanswered.
The fault occurs after edge 3’s update, and a request arrives at edge 4. The checker sees the error, but the old sticky value is still 0. History updates after edge 4. A consumer checking only old sticky can accept the first request if the corrupted payload decodes as PASS; recording it later cannot withdraw acceptance. For example, parity FAIL 00000 XOR mask 00001 gives data 0001 with parity 0. decoded_pass=1 and local_bad=1, while old sticky=0 before edge 4. With valid=ready=1, sticky-only gating accepts.
Use local_bad directly in the grant condition. Use the sticky flag to remember the error. Both ECC policies can use this blocking position.
In the main campaign, a detected storage error persists, so local_bad remains asserted. The table does not separately establish that sticky adds blocked cases. History is useful when an error disappears or state is overwritten; those conditions need their own tests and are not results of this campaign.
checked_q records verification completion. local_bad is the current error-check result. fetch_valid means that the request is valid. fetch_ready means that the downstream interface can accept it.
raw_data is data read before correction. corrected_data is the corrected data. The policy chooses which value becomes selected_data.
assign local_bad = ue | (ECC_REJECT_CE && ce);
assign selected_data = ECC_REJECT_CE ? raw_data : corrected_data;
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) err_sticky_q <= 1'b0;
else err_sticky_q <= err_sticky_q | local_bad;
assign grant = checked_q && (selected_data == 4'b0001)
&& !local_bad && !err_sticky_q;
assign accepted_commit = fetch_valid && fetch_ready && grant;
This circuit blocks in time under the ideal sampling model. A product must also check propagation delays. The check result must settle before acceptance. Subcycle pulses need separate verification too.
SVA describes timing conditions for verification. The assertion below requires authorization for every accepted fetch. The cover checks that a normal authorized fetch remains reachable. Both need a complete verification harness.
assert property (@(posedge clk) disable iff (!rst_n)
accepted_commit |-> (reference_complete && reference_pass));
cover property (@(posedge clk) disable iff (!rst_n)
reference_complete && reference_pass && accepted_commit);
7. Reproduce three counterexamples before reading the counts
Start with a fresh refused meal ticket for each test: parity mask 0x11, complementary mask 0x03, and eight-position mask 0x07. Predict what the desk will see, then compare raw data, corrected data, and handover records. The 342 traces enumerate specified tickets and masks; they are not 342 real attempts. Record rejected legitimate tickets separately to reveal the service cost of conservative rejection.
Download the Python exercise and RTL example. Python uses only its standard library. Run this command to write the results.
python lesson03_register_integrity.py --output-dir lesson03-results
Predict three outcomes first. Use mask 0x11 for parity, 0x03 for complementary encoding, and 0x07 for Hamming. A mask selects the bits to flip.
The first two cases produce valid PASS codewords. The third sets CE. Correct and continue still accepts an unauthorized fetch. Reject on error blocks it.
Read one trace before the totals. What codeword exists after edge 3? What does the checker report before edge 4? Does grant use raw or corrected data? Those steps explain why the same fault has opposite outcomes under the two policies.
We executed the Python experiment. Eight of 342 storage-fault traces had unauthorized acceptance. These counts describe this model’s enumeration. They are not physical attack probabilities.
Expand the complete campaign and verification scope.
Each row fixes the number of flipped bits. Each trace uses one mask. Two accepting edges do not count as two traces.
| Variant | Flipped bits | Traces | Unauthorized traces |
|---|---|---|---|
| Parity | 1 | 5 | 0 |
| Parity | 2 | 10 | 1 |
| Complementary code | 1 | 2 | 0 |
| Complementary code | 2 | 1 | 1 |
| Correct and continue | 1 | 8 | 0 |
| Correct and continue | 2 | 28 | 0 |
| Correct and continue | 3 | 56 | 4 |
| Correct and continue | 4 | 70 | 1 |
| Reject on error | 1 | 8 | 0 |
| Reject on error | 2 | 28 | 0 |
| Reject on error | 3 | 56 | 0 |
| Reject on error | 4 | 70 | 1 |
The program also ran 3,112 codec checks. They cover every payload and the stated flip counts. An independent codebook checks correction results. These checks are separate from the 342 fetch traces.
Eight fault-free controls ran too. Unauthorized controls accepted no fetch. Authorized controls accepted at edges 4 and 6.
Another 23 experiments used an authorized image with one stored-bit flip. Eight correct-and-continue traces still accepted the requests. The other 15 traces blocked them. This also exposes the availability cost of rejection.
Four source-fault traces and four final-grant traces ran separately. They expand the target scope. The sticky-delay counterexample is counted separately too. None belongs to the 342-trace table.
The RTL example includes test injection inputs. Remove them from production circuitry. The harness must restrict mask width and bit count. Parity allows only the lowest five bits. Complementary encoding allows only the lowest two bits.
Python ran; RTL simulation did not. Synthesis, formal proof and silicon testing also did not run. The SVA examples are not completed proofs.
8. What gaps remain outside the register?
A forged eligibility input can make the printer issue a perfectly valid wrong ticket. Alternatively, the ticket may stay correct while final handover permission is changed to true. These are separate source and grant experiments, not stored-ticket cases. The desk’s acceptance mechanism and reference remain trusted. Placing several tickets apart also does not demonstrate physical independence of chip storage.
Storage checks address the specified storage problem. They cannot fill every authorization gap. We now examine two different targets.
The first target is upstream auth_ok_i. Flip it to 1 before capture at edge 2. The encoder produces a valid PASS codeword. All four variants accept unauthorized fetches.
The second target is final grant. Flip its blocking value at edge 4. The interface accepts the first fetch. The upstream codeword remains correct. All four variants fail against this added target.
Downstream handshake and acceptance remain trusted. This experiment faults grant immediately before acceptance, not consumer-internal buffers or fetch_ready. It does not establish coverage of every location inside the consumer.
Extra stored bits do not establish physical independence. Registers can be close together. They can share clocks, resets or sources. Synthesis can also merge redundant logic.
OpenTitan’s implementation guidelines discuss these issues. They recommend local reactions alongside alerts. They also warn that synthesis can merge redundant logic. Examine the actual structure after synthesis. OpenTitan hardware guidelines
9. Read each paper with a question
For another ticket system, first ask how many positions may change, whether it checks printing, storage, or handover, and whether repaired tickets may still collect. These correspond to bit budget, data path, and ECC policy. A physical experiment affecting more positions changes the model premise. It does not establish that this lesson’s mask is achievable on every chip.
Read the model before the protection result. Use these four questions for your notes. Each question matches a boundary in this lesson.
- Does storage protection cover the complete data path? Tollec and colleagues analyze fault-protection boundaries in secure CPUs. They also correct related OpenTitan issues. Follow the protection boundary around the register file. Fault-Resistant Partitioning of Secure CPUs for System Co-Verification against Faults
- Can physical faults exceed the bit budget? Bartkewitz and colleagues evaluate coded countermeasures with laser faults. Their target is a SKINNY implementation in a 40 nm ASIC. Compare physical effects with model assumptions. We did not reproduce their experiment. Beware of Insufficient Redundancy
- Which locations does the tool result cover? VerFI, presented at HOST 2020, analyzes fault behavior. Record its model and test conditions first. A bounded tool result does not establish a physical guarantee. Cryptographic Fault Diagnosis using VerFI
- What changes when another target is added? SYNFI’s OpenTitan case separates output faults from upstream control faults. Compare that distinction with our source fault. SYNFI author version, Section 4.1.2
Grok provided independent literature research. Claude checked the counterexamples and reviewed the completed lesson. Codex verified primary sources and built the lesson. External opinions supplied review leads. The campaign counts come from the executed Python exercise.
10. Change one assumption before choosing protection
Allow one altered position, then three in one event, then add the printing source as a target. The same desk rules now face different problems. One position can be corrected to original eligibility; three-position 0x07 can be miscorrected; a wrong source can print a valid ticket. Choose protection against those explicit model cards rather than treating ECC as a completed policy. Also account for legitimate students who may lose service.
First, allow only one stored-bit flip. Parity and complementary encoding expose the error. Hamming can restore the original data. The designer must still decide whether processing can continue after an error.
Next, allow three flips in one event. Correct and continue now has new unauthorized-acceptance counterexamples. Reject on error blocks them in this model. That result still requires a trusted checker and blocking path.
Finally, add the source to the target set. A wrong source can create a valid codeword. The design then needs additional authorization binding. The next lesson examines multi-bit control signals.
Return to the opening failure. Whether check bits prevent release depends on fault location, bit count and policy. Choose the model, select the encoding, then follow the decision to acceptance. A specification that merely says “has ECC” leaves those questions open. The next lesson examines the source and use of multi-bit controls.
This lesson omits the following details. Study them according to your product’s needs.
- Subcycle pulses, X states and metastability.
- Synthesized logic, layout and common failures.
- Clock/reset faults and debug entry points.
- Recovery and service availability after errors.
- Physical attack calibration and side-channel leakage.
MY ACADEMY · LESSON FILM
Lesson video
The film explains this lesson’s data path. After a section, return to the interactive exercise and change the input or fault conditions. The animation presents a teaching model; it does not replace RTL simulation.
Narration uses a synthetic voice. Both the interaction and animation have model boundaries; interpret results using this lesson’s sources and validation scope.
MY ACADEMY · RTL LAB
Operate codewords: how can valid data give wrong authorization?
Start with parity and flip bits 0 and 4. Watch 00000 become the valid word 10001. Flip both complement bits, then try the ECC continue-policy 0x07 example to inspect miscorrection.
Bits are numbered from right to left; bit 0 is least significant. One event has one target. A source or final-grant fault clears the stored mask so each boundary is tested separately.
Evidence scope: a finite two-state teaching model ported from the existing Python exercise, observing edges 0–7. The independent reference, clock/reset and accepting endpoint remain trusted. No RTL, formal or silicon validation is performed.
SECDED uses this lesson’s custom extended Hamming (8,4). CE is a decoder classification; it does not prove that only one bit was flipped. Faults beyond the correction model can cause miscorrection.
Before this edge samples
After this edge updates
Trace (only edges already visited)
| edge | code Q | decoded | CE / UE | grant | commit | unauthorized |
|---|
Transfer exercise: does a valid codeword prove source authorization? Use the separate source and final-grant cases to locate the gaps in register-only protection.
Download the original Python exercise for an independent rerun
Wrap-up: take this lesson into a design review
- Threat model and assumptions
The goal is to prevent unauthorized fetch acceptance. The main experiment changes only stored codewords. Each trace has one event and one target. Each group fixes the bit budget separately. The fault follows the update at edge 3. Requests occur at edges 4 and 6. Observation ends at edge 7.
The checker and blocking path remain trusted. Clock/reset, completion and handshake remain untouched too. An independent reference records original authorization. These are experimental assumptions. They do not prove physical isolation.
Expanded targets run separately. The source experiment flips only the source at edge 2. The final-grant experiment acts only at edge 4. Neither also injects a storage fault. Other trust assumptions remain unchanged.
- Why the design fails
A fault can change valid FAIL into valid PASS. The two-bit parity counterexample raises no error. The two-bit complementary counterexample also raises no error. A three-bit Hamming fault sets CE. The decoder then miscorrects it to PASS.
Sticky-only gating has a timing gap. The first request can precede the flag update. A wrong source can produce a valid wrong codeword. A corrupted final grant also needs protection at the accepting interface.
- Defenses
Store data and check bits together. Check the stored values on the read path. Compare the complete PASS value before granting. Use the current error directly in blocking. Use sticky state to remember error history.
An authorization result can use reject-on-error policy. Our variant rejects CE and UE. Grant uses no corrected value. It blocks the stated three-bit counterexample. A four-bit valid-codeword replacement still bypasses it. Protect the source and final grant separately.
- Validation and checks to perform
Python ran 3,112 codec checks. Eight of 342 storage-fault traces had unauthorized acceptance. Eight fault-free controls also ran. Another 23 authorized fault cases checked availability. Source and final grant each had four traces. Current blocking was compared with sticky delay.
RTL simulation and formal proof have not run. Synthesis and silicon testing have not run either. A future harness must enforce injection budgets. It must check acceptance timing and normal availability too. Website acceptance is separate from hardware verification.
- Limits and unverified claims
This is a finite two-state sampling model. It excludes subcycle pulses, X and metastability. It also excludes propagation delays and layout effects. Eight out of 342 is not a physical attack probability. A clean observation window does not establish permanent security.
Several registers can be disturbed together. The checker and source can also be attacked. Synthesis can merge redundant logic. These physical boundaries remain unverified. Repeated injection, recovery and side channels are outside this exercise.
Try a changed assumption
Change the budget from one flipped bit to three. Predict whether correct and continue remains safe. Rerun mask 0x07. Then add the source as a target. Explain why a valid codeword can still be unauthorized. Specify the new trusted boundary and acceptance deadline.
This wrap-up summarizes the lesson’s teaching cases, references and experiment scope. Checks not reported as completed remain future work.
Learning guide
RTL Anti-Tampering Design
Open the course outline → · Progress counts published lessons only
Prerequisites
- Basic 0/1 values; Lesson 2 helps with fault models
What I learned
- Distinguish valid codewords from correct authorization
- Compare parity, complementary encoding and SECDED
- Block errors before fetch acceptance
- Separate correction, security and availability