About 29 minutes of class time; Predict is pre-class reading and Explain is a spoken debrief
Checked against
Lab commit ad0235d64da7 on 2026-09-22
NameDate
Predict
Answer these before you open the exhibit. There are no penalties for wrong predictions; the point is to compare them with what you see.
You are about to build an RSA key from p = 257 and q = 263 with public exponent e = 17. Work out n and φ(n) on paper now and write both into the prediction column of the first table under Record. Then write down the equation the private exponent d has to satisfy. You are not expected to solve it yet.
Predict how many multiplications it takes to compute m^17 mod n if you simply multiply m by itself over and over. Then predict how many steps a method that repeatedly squares would need for e = 17, and how many it would need for e = 65537. Write all four numbers into the square-and-multiply table.
The same short message is encrypted twice to the same public key, with no padding. Predict whether the two ciphertexts come out equal, and say what someone watching the wire learns either way. Then: an attacker with no private key takes two ciphertexts, multiplies them together modulo n, and hands the product to the key's owner. Predict what the owner's decryption produces.
A key is published whose modulus n fits in 17 bits. Predict how long a browser tab needs to recover p and q from it, and say what the attacker can compute once it has them.
Do
The exhibit is one page of numbered sections, not tabs. Work top to bottom.
Open the exhibit and go to 2 · Generate a key, step by step. The page has already built a key before you touch anything. Check that Prime p reads 257, Prime q reads 263 and Exponent e reads 17; if any of them differs, type the two primes first, choose Exponent e last, and press Generate. Record the seven rows of the derivation, and the note printed beside each one, in the first table.
Check that Section 2's status line reads the valid-keypair message before going on — the sections below are built from the key generated here.
Go to 3 · Encrypt & decrypt and leave Message (short) reading Hi. Record the three value rows, the two character codes shown under the sentence beginning "How text becomes a number", and the warning line under the heading.
Add one character to the end of Message (short) so the box reads Hii. Record what the status line says. Then delete that character so the box reads Hi again.
Now open Show the encryption math (square-and-multiply). Record the "squarings + multiplies" line while Tiny exponent (e = 3) is the selected button, then press Real key exponent (e = 17) and record that line as well. The number printed in that button is the e your own key uses.
Go to 3½ · The round trip, in one picture. Record the five boxes across the flow — their small top labels read text, encode, ciphertext, recovered and decode — and then the two equation lines beside the clock. Press Replay the round trip; the legend beside the ring names the two hops, so note which of them is drawn first, or note that both appear at once.
Go to 4 · Sign & verify and leave Message to sign as it is. Record the four rows and the verdict line in the "tamper off" column of the sign-and-verify table. Now tick Tamper with the message after signing and record the same four rows and the verdict in the "tamper on" column. Untick it again.
Go to 5 · What breaks at scale. Read the line under the "Your key" heading and record the bit length it reports. Press Factor it! and record the time in the alarm line, the recovered primes, the reconstructed d, the "Anyone can now decrypt" row, and the strategy-and-iterations sentence. On the other card, record the state of Factor it (infeasible) and what that card's last sentence says about where its cost figure comes from.
Go to 6 · Why real RSA adds padding. Record the two textbook ciphertext rows and the verdict under them. Press Run the real OAEP comparison — it builds a 2048-bit key first, so give it a few seconds — and record the first eight characters of each of its two rows, plus its verdict. Finally record the four rows under A second reason: textbook RSA is malleable and the verdict beneath them.
Record
Everything here comes from your own run.
Derivation row in Section 2
My prediction (Predict 1)
Value the page showed
Note printed beside it
p (prime)
blank for your answer
blank for your answer
blank for your answer
q (prime)
blank for your answer
blank for your answer
blank for your answer
n = p · q
blank for your answer
blank for your answer
blank for your answer
φ(n) = (p − 1)(q − 1)
blank for your answer
blank for your answer
blank for your answer
e (public exponent)
blank for your answer
blank for your answer
blank for your answer
d = e⁻¹ mod φ
blank for your answer
blank for your answer
blank for your answer
check: e · d mod φ
blank for your answer
blank for your answer
blank for your answer
Section 3
What I recorded
Message → integer m
blank for your answer
The two character codes shown for H and i
blank for your answer
Ciphertext c = m^e mod n
blank for your answer
Decrypted c^d mod n
blank for your answer
Warning line under the heading
blank for your answer
Status line when the box read Hii
blank for your answer
The first row below has no value from the page; it is your own estimate from Predict 2. Fill the last row in Fix / Extend 6.
Square-and-multiply trace
My prediction: number of steps
The line the page printed
Repeated multiplication, no squaring, e = 17
blank for your answer
blank for your answer
Tiny exponent (e = 3)
blank for your answer
blank for your answer
Real key exponent (e = 17)
blank for your answer
blank for your answer
Real key exponent after Roll random primes
blank for your answer
blank for your answer
Section 3½
What I recorded
text box
blank for your answer
encode box
blank for your answer
ciphertext box
blank for your answer
recovered box
blank for your answer
decode box
blank for your answer
The e · d line
blank for your answer
The line writing that product as a multiple of φ
blank for your answer
Which hop was drawn first
blank for your answer
Section 4 row
Tamper off
Tamper on
H(message) signed
blank for your answer
blank for your answer
Signature s
blank for your answer
blank for your answer
Delivered message verifier sees
blank for your answer
blank for your answer
Recovered s^e mod n vs fresh H(m)
blank for your answer
blank for your answer
Verdict line
blank for your answer
blank for your answer
Section 5
What I recorded
Bit length the card reports for my key
blank for your answer
Time in the alarm line
blank for your answer
Recovered primes p, q
blank for your answer
Reconstructed private d
blank for your answer
Anyone can now decrypt
blank for your answer
Strategy and iterations
blank for your answer
Does that d match the d in the first table?
blank for your answer
State of Factor it (infeasible)
blank for your answer
What the card says about where its cost figure comes from
blank for your answer
Section 6
What I recorded
Textbook: encrypt once
blank for your answer
Textbook: encrypt again
blank for your answer
Textbook verdict line
blank for your answer
OAEP: encrypt once, first eight characters
blank for your answer
OAEP: encrypt again, first eight characters
blank for your answer
OAEP verdict line
blank for your answer
a, and Enc(a)
blank for your answer
b, and Enc(b)
blank for your answer
Enc(a)·Enc(b) mod n
blank for your answer
That decrypts to
blank for your answer
Verdict line
blank for your answer
Explain
Look at your d = e⁻¹ mod φ and check: e · d mod φ rows, and at the aside headed WHAT IS φ?. In its wording, say what φ(n) counts, why (p − 1)(q − 1) is that count when n = p · q, and why d is inverted modulo φ rather than modulo n. Then say which of your seven rows someone holding only n and e cannot fill in.
Copy your two equation lines from the Section 3½ table and check the arithmetic yourself. Using the paragraph printed beside them, explain why raising to d undoes raising to e. That paragraph closes with a smaller note about gcd(m, n) = 1: say what it states is needed to cover every m below n, and which two named results it says do that work.
Section 5 reconstructed a private exponent without being given one. Using your strategy-and-iterations sentence, say what that attack had to search through, and compare its reconstructed d with the d in your first table. Then, using the two panels in 1 · The big idea: a trapdoor and the last sentence on the 2048-bit card, say what the page claims is different about a 2048-bit modulus, and what it says it did not do to arrive at that figure.
The signature row did not change when you ticked the tamper box, but the verdict did. Using the "Recovered s^e mod n vs fresh H(m)" row, say which of those two values changed and why, and what the verifier had to know in order to compute each of them. Then quote the reason the warning under the Section 4 heading gives for calling these signatures forgeable.
Name the two properties of textbook RSA that Section 6 demonstrates, and point to the recorded row that is your evidence for each. Compare the textbook ciphertext you recorded in Section 6 with the one you recorded in Section 3: are they the same number, and why? Then say what changed in the OAEP rows, and what the sentence under the malleability rows claims OAEP's padding does to a product of ciphertexts.
Fix / Extend
Fix. A service generates RSA keys by drawing p and q from a short list of small primes, much like the values suggested in Prime p and Prime q here. Using your Section 5 row — the time, the iteration count and the recovered primes — and the two cards in that section, name the change the page supports, and say which of your recorded Section 5 values would read differently afterwards, and why.
Fix. A product encrypts short, fixed-format tokens with textbook RSA and stores the ciphertexts. Using your Section 6 rows, say what someone who sees only the stored ciphertexts can work out. The closing line of Section 6 names one padding scheme for encryption and another for signatures: name both, and say which of your Section 6 rows would read differently under the encryption one.
Extend. In 3 · Encrypt & decrypt, open Show the encryption math (square-and-multiply) again, and put the two lines you recorded in the square-and-multiply table beside each other. For each line, is the total the page prints smaller or larger than the number it prints after "not"? Use the per-bit rows under each trace — one row per exponent bit, each marked as a multiply or a skip — to say where every multiply came from, and what has to be true of an exponent before this method saves work.
Extend. In 2 · Generate a key, step by step, press Roll random primes. The page draws two fresh primes and rebuilds the derivation from them, so write down the Prime p, Prime q and Exponent e it now shows, together with the trace rows for n, φ(n) and d. Those numbers are yours alone: they will not match your neighbour's. Then put the class key back: type 257 into Prime p and 263 into Prime q, choose 17 in Exponent e, and press Generate.
Extend. Still in Section 2, press Try a too-small / repeated prime. Write down what the status line says and where the link inside it points. Then type 9 into Prime p, press Generate, and write down that message too; note that no derivation is left on screen either time. Put the class key back when you are done — 257 in Prime p, 263 in Prime q, 17 in Exponent e, then Generate.
Extend. Press Roll random primes again. In Section 3, open Show the encryption math (square-and-multiply) and press the second of the two exponent buttons — the one that read Real key exponent (e = 17) on the class key, and that now carries your new key's exponent instead. Record that line in the last row of the square-and-multiply table and compare it with the other two. Then press Factor it! again and compare the time, the iteration count and the bit length the card now reports with your first run.
Extend. In Section 2 set Prime p to 11 and Prime q to 13, take whichever value Exponent e offers first, and press Generate. Record what Section 3's status line now says, what the text and decode boxes of the Section 3½ flow show, and — after pressing Run the real OAEP comparison again — what each of the two blocks in Section 6 says it encrypted. Say which message each part of the page fell back to, and whether the two halves of the Section 6 comparison are still encrypting the same thing. Put the class key back when you are done.
About 32 minutes of class time; Predict is pre-class reading and Explain is a spoken debrief
Checked against
Lab commit 2152e7023198 on 2026-09-22
NameDate
Predict
Answer these before you open the exhibit. There are no penalties for wrong predictions; the point is to compare them with what you see.
The same short message, with no padding, is encrypted to three different recipients whose public keys all use e = 3. An attacker intercepts all three ciphertexts and knows all three public moduli, and never sees a private key. Predict whether the message can be recovered, and name the two things the attacker would have to compute. Write your prediction in the first table under Record.
Now the same message goes to three recipients using e = 65537 and OAEP padding instead. Predict whether the same attack recovers it, and say which change you think does the work — the larger exponent, or the padding.
A service answers exactly one question about any ciphertext you hand it: is the decryption PKCS#1 v1.5 conformant, yes or no. It never returns plaintext and never says anything else. Predict roughly how many questions it takes to recover one short plaintext under a 16-byte modulus — tens, thousands, tens of thousands, or more — and explain your guess.
An attacker who cannot decrypt anything multiplies an intercepted ciphertext c by sᵉ mod n, for a multiplier s of their own choosing. Predict what happens to the plaintext hidden inside that ciphertext, and say whether the attacker gets to see the result.
Do
Steps 1 to 6 are on the Small Exponent Attack tab; steps 7 to 12 are on the Bleichenbacher Oracle tab. Press the buttons in the order given: each panel reveals its next card only once the previous step has run.
Open the exhibit and choose the Small Exponent Attack tab. Read the description under the panel title, then the card Pick Your Config — Will Your Message Survive?.
Press the configuration card Faster boot, simpler code, the one marked e = 3 · padding = none (textbook). Record the headline the result box shows and what its text says happened to the message.
Press the other card, NIST-recommended defaults, marked e = 65537 · padding = OAEP-SHA256. This one builds three full-size RSA keys before it runs, so give it a few seconds. Record its headline and the recovered value its text reports.
Scroll to Setup — Three Recipients, e=3 (Manual) and press Generate 3 Recipient Keys (e=3). Three recipient cards appear. Record the first eight hex digits of n₁ (modulus), n₂ (modulus) and n₃ (modulus).
In Message (max 6 chars for demo), replace the suggested text with up to six ordinary letters or digits of your own, then press Broadcast to 3 Recipients. Record the first eight hex digits of c₁ = m³ mod n₁, c₂ = m³ mod n₂ and c₃ = m³ mod n₃.
Press Execute CRT + Cube Root Attack. Record the line under Message Recovered Without Private Key and whether it matches what you typed, then read the What just happened sentence below it.
Open the Bleichenbacher Oracle tab. Read PKCS#1 v1.5 Encryption Padding Structure and write down, in the fourth table, what the page says "conformant" means.
Press Generate Demo Key + Conformant Ciphertext. Record the first eight hex digits of Modulus n (128-bit), the value shown under e (public exponent), and the Target message.
Go to the card The Padding Oracle. The box under Test ciphertext (hex) — try any value: is already filled with the intercepted ciphertext. Press Query Oracle and record the answer the log shows. Then replace the contents of that box with 01, press Query Oracle again, and record that answer.
In Execute Bleichenbacher Attack, press Show Enc(a) × Enc(b) = Enc(a × b). Record what the page prints for Enc(a) × Enc(b) mod n and for Enc(a × b) directly, and the verdict line beneath them.
Press Run Attack (Auto). Watch the interval bar and the cells under Plaintext recovery — bytes that are uniquely determined by the current interval [a, b]. When the run stops, record Oracle queries, Iterations, Interval bits remaining, the recovered plaintext line, and the last line of the attack log.
Press You Are the Oracle (step through). For each of the first five queries, read the two bytes the panel shows you, answer CONFORMANT or NOT CONFORMANT truthfully, and record the two bytes, your answer and the feedback line. Then read Total queries, press Let the machine finish, and record the recovered plaintext line for this second run.
Record
Everything in these tables comes from your own run. Where a value is long hex, the first eight digits are enough.
Configuration you picked
My prediction: recovered, or not?
Headline the result box showed
What its text reported about the message
Faster boot, simpler code
blank for your answer
blank for your answer
blank for your answer
NIST-recommended defaults
blank for your answer
blank for your answer
blank for your answer
Recipient
Modulus nᵢ, first 8 hex digits
Ciphertext cᵢ, first 8 hex digits
1
blank for your answer
blank for your answer
2
blank for your answer
blank for your answer
3
blank for your answer
blank for your answer
Håstad run
What I recorded
Message I typed
blank for your answer
Recovered message line
blank for your answer
Does it match what I typed?
blank for your answer
Bleichenbacher setup
What I recorded
What the page says "conformant" means
blank for your answer
Modulus n, first 8 hex digits
blank for your answer
e (public exponent)
blank for your answer
Target message
blank for your answer
Oracle query
Value I sent
Oracle's answer
Pre-filled ciphertext
blank for your answer
blank for your answer
01
blank for your answer
blank for your answer
Homomorphism demo
What the page printed
Enc(a) × Enc(b) mod n
blank for your answer
Enc(a × b) directly
blank for your answer
Verdict line
blank for your answer
Attack run
Oracle queries
Iterations
Interval bits remaining
Recovered plaintext line
Run Attack (Auto)
blank for your answer
blank for your answer
blank for your answer
blank for your answer
You Are the Oracle, then Let the machine finish
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Hand-answered query
First byte
Second byte
My answer
Feedback line
1
blank for your answer
blank for your answer
blank for your answer
blank for your answer
2
blank for your answer
blank for your answer
blank for your answer
blank for your answer
3
blank for your answer
blank for your answer
blank for your answer
blank for your answer
4
blank for your answer
blank for your answer
blank for your answer
blank for your answer
5
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Total queries after five decisions
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Explain
The card Attack — CRT Reconstruction + Cube Root states that m³ is smaller than n₁·n₂·n₃, so the Chinese Remainder Theorem gives exactly M = m³. Using your own three moduli and three ciphertexts, explain why three intercepted ciphertexts were enough, and point out where a private key would have been needed in that argument and was not.
Your two configuration runs disagreed. Using the card Why OAEP Destroys This Attack, say which of its bullets breaks the CRT step and which breaks the cube-root step. Then quote what the safe run reported as the recovered value, and explain why that is what a failed attack looks like on this panel.
Your two oracle queries in step 9 came back differently. Using the page's own definition of conformant — EM[0] == 0x00 and EM[1] == 0x02, equivalently m in [2B, 3B−1] — say precisely what the attacker learns from each of the two answers, and why "not conformant" is still worth a query.
Using your homomorphism row and the paragraph above the attack buttons, explain how multiplying c by sᵉ moves the hidden plaintext to m × s without anything being decrypted, and why a conformant answer to that modified ciphertext narrows the interval [a, b] around m.
Compare Total queries after your five hand-answered decisions with Oracle queries from the automatic run. What does that comparison tell you about a human acting as the oracle, and about a server that answers this question quickly? Then name, for each of the two attacks you ran today, the configuration choice that made it possible, and what the page gives as the fix for it.
Fix / Extend
Fix. You maintain a service that decrypts PKCS#1 v1.5 ciphertexts and returns a distinct error when the padding is wrong. Using the card Why TLS 1.3 Removed RSA Key Exchange Entirely, list the changes that card supports, and say for each one which part of your step 11 run it takes away: the one-bit answer, the key exchange itself, or the padding scheme.
Fix. An internal service broadcasts the same unpadded status message to three regional endpoints, each with its own RSA key and e = 3. Using the bullets on Why OAEP Destroys This Attack, name a change that card supports that would stop your step 6 attack, say which of your recorded values would look different afterwards, and say why you chose that change over the others it lists.
Extend. Press You Are the Oracle (step through) again, and on one query answer CONFORMANT when the two bytes shown are not 00 and 02. Record the feedback line, then press Let the machine finish and record what the attack finally reports. Explain why the page re-encrypts its candidate before it calls anything recovered. If the run does not stop on its own, press Abort and record the last line of the log instead.
Extend. Press Generate 3 Recipient Keys (e=3) again, broadcast the same message you used in step 5, and run the attack again. Record whether c₁, c₂ and c₃ changed, and whether the recovered message changed. Using the card's own description of what that button does, say which part of the run supplied the new values.
Point Arithmetic
Exhibit
Point Arithmeticlive exhibit: https://systemslibrarian.github.io/crypto-lab-ec-point-arithmetic/
Time
About 17 minutes of class time; Predict is pre-class reading and Explain is a spoken debrief
Checked against
Lab commit ce6c3d3eb0c2 on 2026-09-22
NameDate
Predict
Answer these before you open the exhibit. There are no penalties for wrong predictions; the point is to compare them with what you see.
The exhibit adds two points P and Q on a curve y² = x³ + ax + b by this rule: draw the line through P and Q, find where it meets the curve a third time, and reflect that point across the x-axis. Sketch a curve, put two points on it, and predict where P + Q lands relative to the third intersection. Then predict what the rule can return when the line through P and Q is vertical.
The exhibit runs the same formulas a second time with every coordinate reduced modulo a prime, the smallest being p = 17. Predict what the set of points looks like once you do that, and whether the slope of a "line" still makes sense. Predict what kind of numbers the slope and the resulting coordinates will be.
k · G means adding G to itself k times. For k = 9, predict how many point additions the definition needs. Then, given that doubling a point counts as one operation and that 9 is 1001 in binary, predict the fewest operations a doubling-based method could need. Write both numbers in the fourth table under Record.
One curve in the exhibit has a subgroup of 99 points; the other named curve has about 2 to the 256th. Suppose that recovering k from G and k · G could be done no other way than by trying every multiple of G in turn. Predict the worst-case number of tries on each. Then say whether a method needing about the square root of that number would change your answer for the larger curve.
Do
Open the exhibit and scroll to the panel headed 2 · Point addition: the chord-and-tangent rule. The Over ℝ (geometry) tab is the one open when the page loads. Leave the curve menu on y² = x³ − x + 1. Read the text readout under the controls on the right and record, in the first table, the P line, the Q line, which λ row is shown and the value after its =, and the x₃ and y₃ values. Check that the P + Q line at the foot of the readout repeats the x₃ and y₃ you just wrote down.
Still on Over ℝ (geometry): put keyboard focus on the curve picture by pressing Tab twice from the Over ℝ (geometry) tab button, or by clicking the picture once without moving the mouse. Press the right-arrow key five times, then record the same readings. Press the up-arrow key once and record them again.
Still on Over ℝ (geometry): tick Show −P (the reflection) and note what the picture adds. Then press Tangent (P = Q) in the row of examples under the controls, and record the readings again. One of the rows you have been copying is no longer printed; leave that cell empty.
Still on Over ℝ (geometry): press P + (−P) = O, then press 2P = O (y = 0). For each, record in the third table what the result line says and the sentence printed underneath it.
Choose the Over 𝔽ₚ (real crypto) tab of the same panel. Leave the curve menu on y² = x³ + 2x + 2 mod 17. Read which point is already selected in Point P, then open Point Q and choose (6, 3). Record the same readings in the second table, and again check the result line at the foot of the readout against your x₃ and y₃.
Still on Over 𝔽ₚ (real crypto): press Doubling (P = Q) in the row of examples and record the readings. Then press P + O = P and record, in the third table, the line the readout prints and the sentence underneath it.
Scroll to the panel headed 3 · Scalar multiplication: k · P. Leave Curve, leave Method on Double-and-add (efficient) and leave Scalar k at 9. Copy the cost each of the two cards below the examples prints into the fourth table. Press Step three times, recording the trace row and the accumulator line after each press in the fifth table. Note the row of bits labelled k in binary: above the buttons. Then press Show all and record the live counter on the selected card, the number of trace rows and the final line.
Record
Every value comes from your own run.
Reading, Over ℝ
P
Q
λ: which row, and its value
x₃
y₃
Opening state
blank for your answer
blank for your answer
blank for your answer
blank for your answer
blank for your answer
After five right-arrow presses
blank for your answer
blank for your answer
blank for your answer
blank for your answer
blank for your answer
After one up-arrow press
blank for your answer
blank for your answer
blank for your answer
blank for your answer
blank for your answer
After Tangent (P = Q)
blank for your answer
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Reading, Over 𝔽ₚ
P
Q
λ: which row, and its value
x₃
y₃
Point Q set to (6, 3)
blank for your answer
blank for your answer
blank for your answer
blank for your answer
blank for your answer
After Doubling (P = Q)
blank for your answer
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Example
Tab
The line the readout printed
The sentence printed under it
P + (−P) = O
Over ℝ
blank for your answer
blank for your answer
2P = O (y = 0)
Over ℝ
blank for your answer
blank for your answer
P + O = P
Over 𝔽ₚ
blank for your answer
blank for your answer
For k = 9
Repeated addition
Double-and-add
My prediction from Predict 3
blank for your answer
blank for your answer
The cost its card prints
blank for your answer
blank for your answer
Live counter on the card after Show all
blank for your answer
blank for your answer
Trace rows I counted after Show all
blank for your answer
blank for your answer
The final line in the result card
blank for your answer
blank for your answer
Step press
The trace row as printed
The accumulator line
First
blank for your answer
blank for your answer
Second
blank for your answer
blank for your answer
Third
blank for your answer
blank for your answer
Explain
Your first three rows in the first table describe one rule with different numbers. The panel's opening sentence says: "To add P and Q: draw the line through them, find where it meets the curve a third time, and reflect that point across the x-axis." On the picture the third intersection is labelled −(P+Q) and the sum is labelled P + Q. Using your recorded x₃ and y₃, say what the reflection does to each of the two coordinates, and which of the two printed formulas is the one that carries it out.
In the fourth row of the first table the λ row changed its name and one of your columns went empty. The panel says: "When P = Q, the 'line' is the tangent." Explain what the tangent has replaced, and why the readout stopped printing that row even though its result line still reads P + Q = ….
Both examples you recorded on the Over ℝ rows of the third table ended at the same result. Quote the sentence the page printed under each, and explain from the picture why a vertical line leaves the rule with nothing to reflect. Panel 1 says the curve's points form a group "together with one extra point O — the 'point at infinity'". Using your third table, say what that extra point is there for.
Put your first table beside your second. The two λ rows print different formulas: over ℝ the readout divides, and over 𝔽ₚ it multiplies by a quantity written with ⁻¹ mod 17. The note beside the lattice says: "Same group law — but every coordinate is reduced mod p, so the smooth curve becomes a scatter of points and the 'line' wraps around. The algebra below is identical to the ℝ case." Using both tables, say which parts of the two calculations are the same, which differ, and what has taken the place of division.
Fix / Extend
Fix. A classmate writes in their report: "I recovered the secret k from G and k·G in the exhibit, so I solved an elliptic-curve discrete logarithm." Using the line panel 4 printed when Walk the subgroup stopped, and the sentence beginning "What this isn’t" at the foot of that panel, say what the exhibit actually did. Then rewrite the claim so that it says no more than your own run supports.
Extend. Open the exhibit at the panel headed 3 · Scalar multiplication: k · P, leaving Curve as it loads and Scalar k at 9 so that this run matches the one you made in step 7. Open Method, choose Repeated addition (definition), and press Show all. Record the live counter on the repeated-addition card, the number of trace rows and the final line in the result card; those three complete the repeated-addition column of the fourth table under Record.
Extend. Scroll to the panel headed 4 · Why you can’t go backwards (ECDLP). Press Walk the subgroup and let it run until it stops on its own. Write down the line it printed when it stopped, then copy both rows of the table of curves in that panel: for the toy curve and for secp256k1, the order n and the best generic attack the table gives for each. Do not press the new-secret button beside the walk; the line the walk prints is reproducible from the page's own starting state, and that control replaces it.
Extend. Your two columns in the fourth table reached the same k · G. State each method's cost in terms of k, using the cards' own wording and your two trace-row counts, and say how the number of doublings relates to the row of bits labelled k in binary: above the buttons on panel 3. Then use the line the walk printed and the two curve rows beside it to explain why computing k · G forward is cheap while recovering k from G and k · G is not, and say what the secp256k1 row adds that the toy row does not.
Extend. On panel 3, choose Repeated addition (definition) in Method, type 5000 into Scalar k and press Enter. The page prints a message in place of a trace. Record it, including the number it gives for double-and-add, and check that number against the cost card beside it. Say what the refusal is demonstrating and why the page treats it as part of the lesson rather than an error.
Extend. On panel 2's Over 𝔽ₚ (real crypto) tab, open Finite-field curve and choose secp256k1 (y² = x³ + 7). The lattice is replaced by a note; record what the note says and how many decimal digits the x coordinate of P has. Then on panel 3 choose the same curve in Curve, press k = order → O, and press Show all. Record both cost cards, and compare the number on the repeated-addition card with the secp256k1 subgroup order you copied from panel 4's table of curves.
About 29 minutes of class time; Predict is pre-class reading and Explain is a spoken debrief
Checked against
Lab commit 1de890f5e9f9 on 2026-09-22
NameDate
Predict
Answer these before you open the exhibit. There are no penalties for wrong predictions; the point is to compare them with what you see.
An ECDSA signer holds a secret scalar d and publishes Q = d·G. To sign a message hash e the signer picks a nonce k, computes r as the x-coordinate of k·G reduced mod n, and s = k⁻¹(e + r·d) mod n. The signer now signs two different messages with the same d and the same k. Predict which of r, s and e come out the same across the two signatures and which come out different. Give your reason for each.
Write the two signing equations from question 1 side by side, one per message. Treating d and k as the unknowns and r, s₁, s₂, e₁, e₂ as known, count the equations and count the unknowns. Predict whether someone who never sees the private key can solve for d, and say what the first step of that solution would be.
An attacker instead has only the public key Q and the generator G, and no signatures at all. Predict whether d can be recovered from those two points, and say what makes this case different from question 2.
RFC 6979 computes the nonce from the private key and the message with HMAC-SHA-256 instead of drawing it from a random number generator. Predict what happens to the signature when the same message is signed twice this way, and what happens to the nonce when two different messages are signed. Then say what each answer does to the attack you described in question 2.
Do
Open the exhibit and stay in What Is ECDSA?. Leave Curve on its starting option and press Generate Keypair. Record what Public key Q (compressed) now shows, what the line beginning Private key shows, and the status line at the bottom of the message panel.
In the same section's right-hand panel, leave the text in Message as you found it. Press Sign Random and record Signature (r, s). Press Verify and record the status line. Press Sign Random a second time and record the new Signature (r, s), then press Verify again.
Scroll to The Nonce-Reuse Attack and read Why it works: two equations, two unknowns. Then move to Try it yourself on the toy curve, leave all four sliders at the values they load with, and read the four cards the panel prints below them. Record r from Signature 1, r from Signature 2, both s values, the recovered k, the recovered d, and what the last card reports about the freshly forged signature.
Still in the toy panel, make these changes one at a time and record what the panel says after each. Move Private key d to any other value. Move Reused nonce k to 7, then to 12, then back to the value it loaded with. Finally drag Message hash e₁ until it equals Message hash e₂, then put it back.
Scroll to Now on real 256-bit keys. Before pressing anything, note what the VICTIM box shows in place of Alice's private key. Press Run Full Compromise. Read the five timeline steps, then expand Show the full 256-bit values and record the values listed in the Record table. Note what the VICTIM box shows now.
Press Run Full Compromise a second time and record the same values from the second run.
Scroll to RFC 6979 Deterministic Nonces and press Reset Samples first, so both lists start empty. Leaving Message for comparison as you found it, press Sign Random in this panel twice, then press Sign RFC 6979 twice. Record the rows that appear under Random nonce output and under RFC 6979 output.
Change Message for comparison — add a word — and press Sign RFC 6979 once more. Record the new row. Then press Try the nonce-reuse attack against RFC 6979 and record the status line beneath it.
Record
Every value below comes from your own run. The 256-bit numbers are far too long to copy out: for those, write the first six and the last six digits, which is enough to tell two runs apart.
From the first panel
What it showed
Public key Q (compressed)
blank for your answer
The line beginning Private key
blank for your answer
Press
Signature (r, s) shown
Status line
Sign Random, first press
blank for your answer
blank for your answer
Verify, after the first Sign Random
blank for your answer
blank for your answer
Sign Random, second press
blank for your answer
blank for your answer
Verify, after the second Sign Random
blank for your answer
blank for your answer
Toy panel, sliders as loaded
Value
r in Signature 1
blank for your answer
r in Signature 2
blank for your answer
s₁
blank for your answer
s₂
blank for your answer
Recovered k
blank for your answer
Recovered d
blank for your answer
What the forgery card reports
blank for your answer
Change I made in the toy panel
What the panel reported
Private key d moved to
blank for your answer
Reused nonce k = 7
blank for your answer
Reused nonce k = 12
blank for your answer
e₁ set equal to e₂
blank for your answer
From Show the full 256-bit values
Run 1
Run 2
n (order)
blank for your answer
blank for your answer
e1 = H("Transfer $10 to Bob")
blank for your answer
blank for your answer
e2 = H("Transfer $20 to Charlie")
blank for your answer
blank for your answer
r (shared)
blank for your answer
blank for your answer
s1
blank for your answer
blank for your answer
s2
blank for your answer
blank for your answer
recovered k
blank for your answer
blank for your answer
recovered d
blank for your answer
blank for your answer
victim's real d
blank for your answer
blank for your answer
the match line, in my own words
blank for your answer
blank for your answer
Alice's private key, as the VICTIM box shows it after the run
blank for your answer
blank for your answer
Timeline step
What it reported, in my own words
Step 2 · Spot the reused nonce
blank for your answer
Step 5 · Forge a new signature
blank for your answer
RFC 6979 panel, row by row
k, where the row shows one
r
Random nonce output, first press
blank for your answer
blank for your answer
Random nonce output, second press
blank for your answer
blank for your answer
RFC 6979 output, first press
blank for your answer
blank for your answer
RFC 6979 output, second press
blank for your answer
blank for your answer
RFC 6979 output, after changing the message
blank for your answer
blank for your answer
Status line under Try the nonce-reuse attack against RFC 6979
blank for your answer
Explain
Your two toy signatures printed the same r, and the panel marks that as the tell. Using the signing rule the page prints — r is the x-coordinate of k·G reduced mod n — explain why reusing k forces r to repeat. Then explain why the two s values still came out different.
Take the five numbers the toy panel's recovery works from — r, s₁, s₂ and the two message hashes on the sliders — and list which of them a signer publishes and which the signer is supposed to keep.
Compare your two Run Full Compromise runs. Say which recorded values changed between the runs and which did not. For each value that did not change, point to the line the page prints that explains why it could not.
The note under the finite-field plot, in The Math You Can See, says that multiplying G is easy and that finding k from the highlighted point is the hard problem ECDSA relies on. Alice's public key was on the page from the start, and it did not give up her private key. The compromise recovered that same private key in one press. Say precisely what the attacker had in the second case that she did not have in the first.
Your two Sign RFC 6979 presses on one message, and the third press after you changed the message, gave three rows. Say what each comparison shows about the nonce. Then read the paragraph at the top of RFC 6979 Deterministic Nonces and the status line you recorded, and state both what the page says blocks the attack and what the page says that block rests on.
Fix / Extend
Fix. A hardware wallet signs with a nonce from a random number generator that occasionally restarts from the same seed. Say what an attacker watching that wallet's published signatures would look for, name which of the two signing buttons on this page corresponds to the fix, and state — from the page's own wording — what that fix still depends on.
Fix. You are reviewing a signing service that avoids repeats by taking its nonce from a counter: k = 1 for the first signature, k = 2 for the second, and so on. No nonce is ever reused. Look at the second line of the recovery the toy panel prints, d = (s₁·k − e₁)·r⁻¹, and say what an attacker who can guess k needs in order to run that line, and how many signatures it would take. Say whether the tell you identified in Explain 1 would appear here.
Extend. Open What Is ECDSA?, press Generate Keypair, and press Sign Random once so that a signature exists. Now edit Message — add a word to it — and press Verifywithout signing again. Write down the status line. Restore the original wording, press Verify once more, and write down the status line again. Say whether the signature had to be made a second time for the restored message to pass.
Extend. Still in What Is ECDSA?, with a keypair generated and Message as you found it, press Sign Deterministic (RFC 6979) twice in a row and write down Signature (r, s) after each press. Say whether the two presses agree, and compare them with the two Sign Random signatures in your Record table.
Extend. Work the toy panel's recovery by hand. In Try it yourself on the toy curve, leave the four sliders at the values they load with and take r, s₁, s₂ and the two message hashes from the cards and the slider labels. Then, mod 19, compute k = (e₁ − e₂)·(s₁ − s₂)⁻¹ and d = (s₁·k − e₁)·r⁻¹, working both modular inverses out by hand. Check your k and d against the recovered values the panel prints, and your d against the Private key d slider.
Extend. Scroll to The Math You Can See and work in the right-hand panel, The real thing: a finite field. Move the Walk k·G slider and read the line under the plot. Write down the point the page reports for k = 5, for k = 7, and for one more value of your choosing, then read the note printed below that line.
Extend. Move the Walk k·G slider through each value from 1 to 18 and write down the point for each. Count how many distinct x-coordinates appear. The panel builds r from that x-coordinate, so say how many different r values this toy curve can produce, and what that means for two signatures that happen to share an r.
Extend. Setting Reused nonce k to 7 in the toy panel stops the attack, and the panel names the reason; set it there again if you need the wording in front of you. Now move the Walk k·G slider to 7, read the point the page reports, and work out what r would be for that nonce. Then substitute that r into s = k⁻¹(e + r·d) mod n and say what s reduces to. Does refusing that nonce protect the private key, or does it prevent a different problem?
Extend. Change Curve to the other option and press Run Full Compromise again. Compare n (order), e1 and e2 with the runs you already recorded, and say which of the three the curve choice changed. Note what the status line in the first panel now asks you to do, and why.
Extend. Open ECDSA vs Ed25519 and read the rows Deterministic by default, Nonce reuse catastrophic and Malleable signatures. Say which row the RFC 6979 panel is demonstrating, and name a property the table still records differently for the two schemes once RFC 6979 is in use.
About 30 minutes of class time; Predict is pre-class reading and Explain is a spoken debrief
Checked against
Lab commit 6b023a9e821b on 2026-09-22
NameDate
Predict
Answer these before you open the exhibit. There are no penalties for wrong predictions; the point is to compare them with what you see.
Every ECDSA signature satisfies s = k⁻¹(h + r·d) mod n, which rearranges to the linear congruence r·d − s·k + h ≡ 0 (mod n). Here d is the private key and k is the one-time nonce, and both are unknown; r, s and h are public. One signature is therefore one equation in two unknowns. Now suppose a signer produces two signatures over two different messages using the samek. Write down what an observer would see in the two public signatures that gives the reuse away, then say whether two such equations are enough to solve for d, and why.
To pin down a 256-bit secret, the leakage an attacker collects has to exceed the secret's entropy: leaked bits per signature multiplied by the number of signatures must clear 256. This lab's controls stop at 32 leaked bits per signature and 32 signatures. Predict the smallest number of signatures at which 24 known bits each could be enough, and predict what the lab should say about 24 bits across 4 signatures.
RFC 6979 derives the nonce deterministically from the private key and the message instead of drawing it from a random source. Predict what this attack should report for a batch of RFC 6979 signatures, and predict whether the attacker is left with a lattice that merely fails to give up the key, or with no lattice to reduce at all.
Later you will hold the signature count fixed and vary the leak size until recovery stops working. Predict whether that will be a sharp line — every run above it succeeds, every run below it fails — or a band. Say what you would expect to see from three runs of the same configuration sitting right at the edge.
Do
Open the exhibit. It runs a configuration by itself on load, so wait until the line under the pipeline strip stops reading Running lattice analysis. Read the always-visible panel The one equation everything hangs on and note the rearranged congruence it prints.
In the Configuration panel, set Curve to secp256k1 (Bitcoin), Leak Mode to MSB leak — top bits known, Leak Size (bits) to 24 and Signature Count to 12. Press Generate Attack, the submit button at the foot of that form, and wait for the run to finish.
In the panel headed Can this configuration recover the key?, record the badge beside that heading and the coloured sentence printed under the plot. Then read the closing paragraph of that panel, which begins Reading the axes honestly, and record the curve it names and the bits-per-signature figure it quotes from the classic Hidden Number Problem result.
Four walkthrough steps appear above the analysis panels once a run finishes, in the same order as the pipeline strip. Every new run reopens the first of them. Open the first step and, from the Signature Log table, record for signatures 1 and 2: the leaked_bits entry and the leading digits shown in the r, s, h and SHA-256 columns.
Open the fourth walkthrough step. Record the banner text at the top of the panel, the two lines on the Validation card, and whether any byte in the two-row key grid is marked as not matching. Then scroll to Execution details at the foot of the page and record Signatures and Worker runtime.
Set Leak Mode to Reused nonce — PS3-style and Signature Count to 2, leaving Leak Size (bits) at 24. Press Generate Attack. Record the scenario line under the pipeline strip, the feasibility badge, the two r values in the Signature Log, the banner in the fourth step, and what the third step's Lattice View and Basis View say in place of matrices.
Staying on that run, read the panel headed Two signatures, no lattice needed in the fourth step. Record the two formulas it prints, one for k and one for d, and the value it gives for k.
Set Leak Mode to RFC 6979 — deterministic (secure) and Signature Count to 12, leaving Leak Size (bits) at 24. Press Generate Attack. Record the scenario line, the summary line, the feasibility badge and the sentence under the plot, the banner, the Recovered Key card, the diagnostic sentence printed in the second walkthrough step, and the single line listed under Diagnostics in the fourth.
Still in RFC 6979 mode, press Measure this column and record the reason the panel gives for declining.
Set Leak Mode back to MSB leak — top bits known and Signature Count to 12, then press Measure this column. This runs the real attack several times over at each of several leak sizes, so it takes a while; while it works, the panel says which rung it is on and shows the rungs it has not reached yet as queued. Leave the form alone until it finishes, then record every row of the table it fills in and the verdict paragraph below the table.
Record
Every value below comes from your own run.
Run
Feasibility badge
Scenario line under the pipeline strip
Summary line
Banner in the fourth step
MSB, 24 bits, 12 signatures
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Reused nonce, 2 signatures
blank for your answer
blank for your answer
blank for your answer
blank for your answer
RFC 6979, 12 signatures
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Signature Log (MSB run)
leaked_bits
r
s
h
SHA-256
Signature 1
blank for your answer
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Signature 2
blank for your answer
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Recovery (MSB run)
Value
Validation card, first line
blank for your answer
Validation card, second line
blank for your answer
Execution details: Signatures
blank for your answer
Execution details: Worker runtime
blank for your answer
Reading
Reused-nonce run
RFC 6979 run
Are the r values in the log equal?
blank for your answer
blank for your answer
What the Lattice View shows in place of matrices
blank for your answer
blank for your answer
What the Basis View shows in place of rows
blank for your answer
blank for your answer
Recovered Key card
blank for your answer
blank for your answer
Diagnostic in the second walkthrough step
blank for your answer
blank for your answer
Configuration offered to Measure this column
Reason it gave for declining
RFC 6979, 12 signatures
blank for your answer
Measured column: MSB, 12 signatures
leak bits
recovered
rate
outcome, and milliseconds
Rung 1
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Rung 2
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Rung 3
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Rung 4
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Rung 5
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Rung 6
blank for your answer
blank for your answer
blank for your answer
blank for your answer
Verdict paragraph
Value
Measured boundary, in bits
blank for your answer
Information floor it prints
blank for your answer
Drawn practical curve it prints
blank for your answer
Rungs it names as recovering sometimes
blank for your answer
Explain
In your reused-nonce run the two signatures shared one r. Using the two formulas the derivation panel prints, explain why sharing k makes r repeat, and how the pair of equations then yields first k and then d. Reading the formula for k, say what would have to be true of the two signatures for that arithmetic to break down, and why signing two different messages makes that unlikely.
The RFC 6979 run recovered nothing, and the third walkthrough step had no matrix in it at all rather than a matrix that failed. Using the diagnostic the page printed in the second step and the Why this works paragraph in the fourth, say what RFC 6979 removes from the signing path, and where the page says the security question moves to instead. Then say which of the two failures you reproduced in this exhibit — the reused nonce and the leaked nonce bits — that change addresses, and which one the closing paragraph of the same panel says is left as a separate question.
Compare the feasibility badge you recorded for the reused-nonce run and for the RFC 6979 run against what those two runs actually did. Using the note printed under the plot, say which configurations the gauge is about and which it is not. Write one sentence you would add to that panel to stop a reader drawing the wrong conclusion from the badge alone.
Look at your measured column. Which rungs recovered on some runs and not on others, and what does the verdict paragraph say decides the outcome at those rungs? Compare the measured boundary with the information floor and with the drawn practical curve that the same paragraph prints. Finally, using Reading the axes honestly, explain why your measurement is a statement about this page rather than about secp256k1, and what that paragraph gives as the real reason ordinary keys are safe.
Fix / Extend
Fix. At the foot of the page there is a collapsed section whose summary ends Real-world case studies, timeline, and related labs. Open it and read the Android wallet entry from 2013 and the Minerva entry from 2019. The second walkthrough step lists an Attack Path and a Defense Path side by side. For each of those two incidents, name the Defense Path items that address it, and say which rung of the Attack Path each incident supplied for free. Then say which of the two the RFC 6979 mode you ran demonstrates a fix for, and which it leaves open.
Extend. Run the MSB configuration twice and compare the logs. Set Curve to secp256k1 (Bitcoin), Leak Mode to MSB leak — top bits known, Leak Size (bits) to 24 and Signature Count to 12, press Generate Attack, and wait for the run to finish. Open the first walkthrough step and, from the Signature Log table, record for signatures 1 and 2 the leaked_bits entry and the leading digits shown in the r, s, h and SHA-256 columns. Then press Generate Attack again without changing anything, open the first walkthrough step again, and record the same five values for signatures 1 and 2 a second time.
Extend. Compare the two MSB runs from the item above. Which of the five recorded columns changed between them and which did not? The leaked_bits entry names both how many bits the attacker is given and what value those bits take — what is that value, and what does it tell you about how this demo produces a leak? What does an unchanged SHA-256 column tell you about the messages the two runs signed, and why does that matter when you are deciding which of your recorded numbers a classmate could be expected to match?
Extend. Read the lattice itself. Set Curve to secp256k1 (Bitcoin), Leak Mode to MSB leak — top bits known, Leak Size (bits) to 24 and Signature Count to 12, press Generate Attack, and wait for the run to finish. Open the third walkthrough step and read How one signature becomes one lattice row, then record from the Basis View table how many rows it has and the before and after values on row 1. If the run recovered the key, the key bridge below the two matrices prints a line labelled secretCoordinate / B (mod n); record the hex value on it.
Extend. Collect the other two refusals. With Leak Mode on MSB leak — top bits known and Leak Size (bits) at 24, set Signature Count to 4, press Measure this column, and record the reason the panel gives for declining. Then set Signature Count to 32, press it again, and record that reason. Say how the two reasons differ, and which of the two the panel itself describes as a limit of this page rather than a property of the attack.
Extend. Measure a second column. Leave Leak Mode on MSB leak — top bits known, set Signature Count to 10, and press Measure this column again. Two measured points are now drawn over the modelled curves. Compare the two measured boundaries with each other, and each with the drawn practical curve at its own signature count. What does the pair suggest about whether the drawn curve is optimistic, pessimistic, or about right over this range?
Extend. Set Curve to P-256 (NIST) and press Generate Attack with the same leak mode, leak size and signature count as your first run. Record what changes in the closing Reading the axes honestly paragraph and in Execution details, and what does not change in the bits-per-signature figure it quotes. Explain what that figure depends on, and why two different standardised curves can share it.
Crypto Lab exhibits are teaching demonstrations, not production libraries. Do not use exhibit code to protect real data.