ESP32-S3 Bench Guide
ESP32‑S3 N16R8 벤치 가이드: 실시간 핀아웃, 강의, 시뮬레이터 및 벤치 로그
SM9 기반 신원 키 추출·디지털 서명·키 교환·공개키 암호화, GM/T 0044.5 예제 적용
SM9 identity-based key extraction, digital signature, key exchange and public key encryption, run against the worked examples in GM/T 0044.5.
교육TypeScript · CSSGitHub @systemslibrarian온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Browser-based SM9 identity-based cryptography — signature, key exchange and encryption side by side, with keys extracted from a name by exponent inversion, two master key pairs in mirrored pairing groups, nonce-reuse recovery of a key point rather than a scalar, and the KGC reading everyone's mail
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
SM9 identity-based key extraction, digital signature, key exchange and public key
encryption, run in the browser against the worked examples printed in the standard
itself.README 전문 보기 ↗GM/T 0044 · GB/T 38635 · ISO/IEC 14888-3 · ISO/IEC 18033-5
SM9 identity-based key extraction, digital signature, key exchange and public key encryption, run in the browser against the worked examples printed in the standard itself.
Live demo: https://systemslibrarian.github.io/crypto-lab-sm9-forge/
SM9 is China's identity-based cryptography standard: your identity string is your public key, and an authority called the KGC mints the matching private key. This lab implements the whole family — key extraction, the digital signature algorithm (GM/T 0044.2), the key exchange protocol (GM/T 0044.3), and the key encapsulation mechanism and public key encryption (GM/T 0044.4) — over the 256-bit Barreto-Naehrig curve and R-ate pairing of GM/T 0044.5 clause 3.1.
The thing worth coming for is how the private key is made. Boneh-Franklin IBE, the
scheme most people meet first, hashes an identity to a curve point and multiplies it
by the master secret. SM9 hashes the identity to a scalar, adds the master secret,
and inverts — t1 = H1(ID‖hid, N) + ks, t2 = ks · t1⁻¹, ds_A = [t2]P1. No
hash-to-curve appears anywhere in SM9 key extraction. That one structural difference
pays for itself twice over: SM9 carries two master key pairs in mirrored pairing
groups, so the authority can both read your mail and sign in your name; and the
inversion makes the identity hash cancel out of the verification equation, so a
passing check proves that extraction and verification agreed on a map, not that either
of them used SM9's.
Security model. Every private key in SM9 is derivable by the KGC from the identity alone, by design. There is no forward secrecy against the KGC and no way to opt out: the same two lines of clause 5.3 that define extraction define the escrow. Pane 4 demonstrates both halves of that rather than describing them.
Not production cryptography — a teaching demo. Everything runs in your browser. Key material is per-session and in memory; nothing is persisted and nothing leaves the page.
cid = 0x12 and eid = 0x04 decoded into words, then
H1, H2 and the KDF reproduced against the standard's own printed sub-values with
no pairing running. A deliberately wrong negative control runs beside them and
must be reported as a mismatch.t1 = 0 branch the standard defines
and almost nothing ever reaches.ke it derives any
identity's decryption key and reads the message, and with ks it derives any
identity's signing key and produces a signature this page's own verifier accepts.hid values from one master key, reaching
two different session keys that are labelled by source rather than ranked.The five exhibits are five gated steps, not five panels on a page. A step unlocks
when the step before it has produced a real result — not when its button was pressed,
which is a different claim — so the SM3 layer is reproduced before a key is extracted,
and a key exists before any protocol runs on it. Completed steps collapse to the one
line they earned, with a control to reopen them, and a sticky rail carries anchors
(#step-sm3, #step-extract, #step-protocols, #step-kgc, #step-break) so a
presenter can jump to an act without scrolling through the audit trail.
Nothing is computed that the visitor did not cause. The page used to open with pane 1 saying pending — not yet run directly above pane 2 saying ds_A issued: the headline act had already happened and nobody had pressed anything.
Guided is the default. Full evidence unlocks and expands everything at once and is one control away at the top — progressive disclosure that cannot be switched off is just material hidden from the people most likely to check it. Neither view persists: progress lives in memory and a reload is a full reset, deliberately, because a restored half-run would be restoring verdicts about inputs the reader can no longer see.
Copy run transcript exports the run as JSON — inputs, verdicts, status words, source labels and computed values — read off the rendered page rather than assembled beside it, so it cannot disagree with what the page claimed.
ID‖hid → h1 → t1 → t1⁻¹ → t2 → ds_A fill one operation at
a time.hid divergence beside it.A passing check does not pin which identity-to-scalar map produced the key.
This is the lab's headline finding, and it needs stating precisely because the loose
version of it is false. SM9 verification does check the identity binding:
h1 = H1(ID‖hid, N) feeds P = [h1]P2 + Ppub-s, and a key for another identity, a
key extracted at a different hid, or a key extracted under a non-standard H1 are all
refused at HASH-MISMATCH.
What the equation does not pin is which map both sides used. Extraction sets
t1 = H1 + ks and t2 = ks · t1⁻¹, so t1 · t2 = ks for any H1 whatsoever, and
verification computes u = e(S, P) = e(P1, P2)^(l·ks) — H1 cancels, provided both
sides use the same one. So a KGC and a verifier that agree on a non-standard
identity hash interoperate perfectly, and their green check says nothing about
conformance to SM9. Pane 3 runs exactly that: the same identity and the same hid,
with one extra domain byte in front of H1 on both sides, and the page's own
unmodified verifier accepts — while the row beneath shows SM9's real verifier refusing
the same key.
Conformance is not self-certifying, and the fleet has a real instance of it. The
same structure runs through key exchange, where g1, g2 and g3 are
hid-independent because t3 cancels inside e(R_A, de_B), so hid reaches the
session key only through the KDF input. That is not a hypothetical: GmSSL and the
standard's own Annex B disagree about hid for key exchange, each is internally
consistent, and each produces passing checks against itself. Pane 5 runs both.
The KEM has no integrity check, and public key encryption does. GM/T 0044.4
clause 6.2.1 is: check C is in G1, pair, KDF, output — with an error only if K' = 0.
Decapsulating with a different user key therefore yields a different key silently,
not a failure. Encryption fails closed at the MAC, clause 7.2.1 step B4. The page shows
the two outcomes side by side because the difference is the lesson.
One reused nonce is fatal, and what it costs is a point. Two signatures over
different messages under one r give S1 − S2 = [h2 − h1]ds_A, so
ds_A = [(h2 − h1)⁻¹](S1 − S2). The r cancels — an attacker never needs it. What
comes back is the private key point in G1 and no scalar at all, because an SM9
private key is a group element. SM2 Forge
makes the same mistake and recovers a scalar d; the difference is not the attack, it
is what a private key is.
hid = 0x02 and hid = 0x03 do not interoperate. GM/T 0044.5 Annex B declares
0x03 and reaches SK = 68b20d30…; GmSSL, emmansun/gmsm and Bouncy
Castle use 0x02 for key exchange and reach SK = c5c13a8f…. Both are internally
consistent. The normative text pins no value at all — clause 5.3 says only that the
KGC "selects a one-byte identifier hid and makes it public".
Two lines of Annex B are misprinted, in the Chinese original as well as the English.
Inside an otherwise-0x03 example, two lines print the hid byte as 02. They are
typos, established three ways: the H1 digest printed beside each is byte-identical to
the 0x03 digest printed in key extraction; H1("Bob"‖0x02) appears nowhere in the
document; and taking the bytes literally makes the two sides disagree, while the
annex itself prints SK_A == SK_B. Transcribing those lines literally will not
reproduce R_A. This does not establish why GmSSL chose 0x02 — that is an
inference nobody has confirmed, and GmSSL documents no reason.
SM9 is standardised domestically as GM/T 0044-2016 (five parts) and GB/T 38635-2020 (two parts), both in force in different standards systems. Internationally, its signature is ISO/IEC 14888-3:2018 clause 7.4, under the name "Chinese IBS", and its key encapsulation is ISO/IEC 18033-5:2015/Amd 1:2021, "Amendment 1: SM9 mechanism", clause 9.4.
npm ci
npm run dev
npm test runs the unit suite, the known-answer tests and the CSP hash guard.
npm run test:oracle runs the independent cross-check. npm run test:e2e runs the
claims suite, npm run test:a11y the accessibility gate and npm run test:geometry
the visual-quality gate; all three need npx playwright install chromium first.
The browser gates build first and serve the production build on port 4646, which is
this lab's own rather than Vite's default 4173. That is not a preference: several labs
in this fleet kept the default, and reuseExistingServer then hands the suites whatever
is already answering on it — a cold run here was silently judged against
crypto-lab-glass-box until the port was changed. All three places that name it
(use.baseURL, webServer.command, webServer.url) live in playwright.config.ts.
The production type-check uses the native TypeScript 7 compiler. The SM3 and
SM4 packages currently declare TypeScript 5 JavaScript-API peers, so that API
stays installed side-by-side; npm run check:typescript guards both identities
and strict native-compiler rejection controls without bypassing peer validation.
419 unit tests, 35 rendered-verdict claims tests, a 26-test independent cross-check and a 5-test geometry gate. The accessibility gate scans the production build at 1280px and 380px across 20 driven states each — the guided path a visitor actually walks, including the locked, collapsed and Full-evidence renderings — and blocks the deploy on any WCAG 2.1 A/AA violation.
The geometry gate is the one axe cannot run. It measures the landing page's height, where the first meaningful action sits in the viewport, the hero's stacked gap at phone width, and the painted size of every text run. It exists because the two pane-2 SVG diagrams passed the accessibility gate while rendering their labels at roughly five CSS pixels on a phone: the contrast oracle measured them correctly, and contrast is not legibility. Both diagrams are HTML now, and the rule that caught them is a test.
Known-answer tests. Every figure comes from GM/T 0044.5, fetched directly from
gmbz.org.cn (md5 40cee7ca9ab2b885dee2158b2d4a12cc) and pinned in
src/sm9/fixtures/. Annex A signature 47/47 including all eight must-reject cases,
Annex B key exchange 37/37, Annex C KEM 25/25, Annex D encryption 53/53 across both
modes, failure direction 15/15. The BN256 constants are not merely transcribed: their
test re-derives q, N and the trace from t using the standard's own polynomials.
The independent cross-check shares no code path with the runtime — GmSSL C's own
pinned vectors from tests/sm9test.c, plus OpenSSL's SM3 through node:crypto driving
the same H1/H2/KDF constructions. It is not decorative: writing it caught a mis-derived
assertion, where hex_fn_nsub turned out to be the reverse subtraction y − x rather
than N − x.
A multi-block H1 case had to be generated. Every H1 input in the entire standard is
an identity plus one hid byte — 4 to 6 bytes — so H1 never crosses a 64-byte SM3
block anywhere in the annexes. H2 and the KDF are already multi-block there (404, 451
and 1288 bytes). The generated cases run at 49, 50, 60, 62, 119 and 200 bytes and are
cross-checked three ways.
The pairing engine is vendored, and was verified before use.
src/vendor/gmssl-sm9.js is GmSSL-JS's js/sm9.js, Apache-2.0, with its notice
preserved. The single change is at the end of the file: the bare pairing_test() call
was removed and the function exported instead, because upstream's self-check only
console.logs a boolean and exits 0 whether it passes or fails. It was driven through
65 of GmSSL C's own hex_* vectors plus 24 consistency checks covering the branches
that have no C vector.
g, w, u and w' are the standard's printed values
agreeing with GmSSL-JS, not two independent pairing engines agreeing. No second
browser-capable SM9 pairing implementation exists to close this.GB/T 41389-2022 has not been read by anyone who worked on this lab. It is
reportedly where the hid = 1 / hid = 3 convention is actually pinned, which makes
it the most load-bearing document for the hid question, and it is cited here as
unread rather than summarised second-hand.hid = 0x02 attributions were read, not inherited. GmSSL, emmansun/gmsm
and Bouncy Castle were each checked in source. Bouncy Castle declares
HID_EXCHANGE = (byte)0x02 in
core/src/main/java/org/bouncycastle/crypto/params/SM9EncMasterPrivateKeyParameters.java,
and its own comment there attributes the value to the Chinese edition of the
GM/T 0044.5-2016 Annex B worked example, noting the official English edition of the
same annex chose 0x03. That last attribution is Bouncy Castle's claim about the
two editions, quoted rather than confirmed here — this lab has not compared the two
editions itself, and says so on the page.@lryncloud/crypto is not SM9, and should not be used. Its G1 and G2 elements are
bare scalars, its "pairing" multiplies two scalars mod n, GT is a single integer, and
its signature is s = d·h mod n — while it pins the genuine SM9 q, n, P1 and
hid bytes so the parameter file looks authentic. It hashes domain-separation strings
such as "SM9-H1-SIGN" in place of H1's 0x01-prefixed two-block counter chain. At the
time of writing no vetted browser-capable SM9 package exists on npm: @li0ard/sm9 does
not exist, and gmssl-node is a native addon that cannot run in a browser and exposes
no way to load a pinned master key.
One R-ate pairing measures median 12.92 ms, p95 17.64 ms in Node on an Apple M5 (n = 50, warmed). In the browser it is roughly 4-5 ms in Chromium and 18-22 ms in Firefox. Verification costs two pairings and is comfortable everywhere; key exchange costs several. These are measurements of one machine and one build, not a benchmark of SM9.
Post-exTNFS estimates for a BN curve with a 256-bit prime differ between published sources, and both are quoted here rather than averaged or picked between: Menezes, Sarkar and Singh give "a conservative estimate … is 110 bits" (ePrint 2016/1102, Remark 6); Barbulescu and Duquesne, arguing the former is not precise enough, give "in fact 100 bits". Neither is this lab's own measurement.
MIT — see LICENSE.
One of the browser demos in the Crypto Lab suite.
"So whether you eat or drink or whatever you do, do it all for the glory of God." — 1 Corinthians 10:31