Skip to content

Commit 9189afb

Browse files
guest271314bsmthtwiss
authored
Add Ed25519 sign-verify example (mdn#247)
* Add Ed25519 sign-verify example * Create ed25519.js * Link to Chromium and Chrome command-line switch to enable the feature * Close </a> * Apply suggestions from code review Co-authored-by: Daniel Huigens <d.huigens@protonmail.com> * docs(web-crypto): add link to browser compat for ed25519, formatting * Update web-crypto/sign-verify/index.html Co-authored-by: Daniel Huigens <d.huigens@protonmail.com> --------- Co-authored-by: Brian Thomas Smith <brian@smith.berlin> Co-authored-by: Daniel Huigens <d.huigens@protonmail.com>
1 parent d529271 commit 9189afb

File tree

3 files changed

+254
-76
lines changed

3 files changed

+254
-76
lines changed

web-crypto/sign-verify/ed25519.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
(() => {
2+
/*
3+
Store the calculated signature here, so we can verify it later.
4+
*/
5+
let signature;
6+
7+
/*
8+
Fetch the contents of the "message" textbox, and encode it
9+
in a form we can use for sign operation.
10+
*/
11+
function getMessageEncoding() {
12+
const messageBox = document.querySelector("#ed25519-message");
13+
let message = messageBox.value;
14+
let enc = new TextEncoder();
15+
return enc.encode(message);
16+
}
17+
18+
/*
19+
Get the encoded message-to-sign, sign it and display a representation
20+
of the first part of it in the "signature" element.
21+
*/
22+
async function signMessage(privateKey) {
23+
const signatureValue = document.querySelector(".ed25519 .signature-value");
24+
signatureValue.classList.remove("valid", "invalid");
25+
26+
let encoded = getMessageEncoding();
27+
signature = await window.crypto.subtle.sign("Ed25519", privateKey, encoded);
28+
29+
signatureValue.classList.add("fade-in");
30+
signatureValue.addEventListener("animationend", () => {
31+
signatureValue.classList.remove("fade-in");
32+
});
33+
let buffer = new Uint8Array(signature, 0, 5);
34+
signatureValue.textContent = `${buffer}...[${signature.byteLength} bytes total]`;
35+
}
36+
37+
/*
38+
Fetch the encoded message-to-sign and verify it against the stored signature.
39+
* If it checks out, set the "valid" class on the signature.
40+
* Otherwise set the "invalid" class.
41+
*/
42+
async function verifyMessage(publicKey) {
43+
const signatureValue = document.querySelector(".ed25519 .signature-value");
44+
signatureValue.classList.remove("valid", "invalid");
45+
46+
let encoded = getMessageEncoding();
47+
let result = await window.crypto.subtle.verify(
48+
"Ed25519",
49+
publicKey,
50+
signature,
51+
encoded
52+
);
53+
54+
signatureValue.classList.add(result ? "valid" : "invalid");
55+
}
56+
57+
/*
58+
Generate a sign/verify key, then set up event listeners
59+
on the "Sign" and "Verify" buttons.
60+
*/
61+
window.crypto.subtle
62+
.generateKey("Ed25519", true, ["sign", "verify"])
63+
.then((keyPair) => {
64+
const signButton = document.querySelector(".ed25519 .sign-button");
65+
signButton.addEventListener("click", () => {
66+
signMessage(keyPair.privateKey);
67+
});
68+
69+
const verifyButton = document.querySelector(".ed25519 .verify-button");
70+
verifyButton.addEventListener("click", () => {
71+
verifyMessage(keyPair.publicKey);
72+
});
73+
});
74+
})();

web-crypto/sign-verify/index.html

Lines changed: 120 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,72 @@
11
<!DOCTYPE html>
22
<html lang="en">
33
<head>
4-
<meta charset="utf-8">
4+
<meta charset="utf-8" />
55
<title>Web Crypto API example</title>
6-
<link rel="stylesheet" href="style.css">
6+
<link rel="stylesheet" href="style.css" />
77
</head>
88

99
<body>
1010
<main>
1111
<h1>Web Crypto: sign/verify</h1>
1212

1313
<section class="description">
14-
<p>This page shows the use of the <code>sign()</code> and <code>verify()</code> functions of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API">Web Crypto API</a>. It contains four separate examples, one for each signing algorithm supported:</p>
15-
<ul>
14+
<p>
15+
This page shows how to use the <code>sign()</code> and
16+
<code>verify()</code> functions of the
17+
<a
18+
href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API"
19+
>Web Crypto API</a
20+
>. It contains examples for the following signing algorithms:
21+
</p>
22+
<ol>
1623
<li>"RSASSA-PKCS1-v1_5"</li>
1724
<li>"RSA-PSS"</li>
1825
<li>"ECDSA"</li>
1926
<li>"HMAC"</li>
20-
</ul>
21-
<hr/>
27+
<li>
28+
"Ed25519"
29+
<ul>
30+
<li class="caution-list-item">
31+
<span class="caution">Caution: </span>For information about
32+
Ed25519 support, see
33+
<a
34+
href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto#browser_compatibility"
35+
>SubtleCrypto: Browser compatibility</a
36+
>
37+
and
38+
<a
39+
href="https://blogs.igalia.com/jfernandez/2023/06/20/secure-curves-in-the-web-cryptography-api/"
40+
>Secure Curves in the Web Cryptography API</a
41+
>. Chrome requires the
42+
<code>enable-experimental-web-platform-features</code>
43+
preference to be set via
44+
<a
45+
href="https://peter.sh/experiments/chromium-command-line-switches/#enable-experimental-web-platform-features"
46+
>command-line switch</a
47+
>
48+
or via
49+
<code
50+
>chrome://flags/#enable-experimental-web-platform-features</code
51+
>.
52+
</li>
53+
</ul>
54+
</li>
55+
</ol>
56+
<hr />
2257
<p>Each example has four components:</p>
2358
<ul>
2459
<li>A text box containing a message to sign.</li>
2560
<li>A representation of the signature.</li>
26-
<li>A "Sign" button: this signs the text box contents, displays part of the signature, and stores the complete signature.</li>
27-
<li>A "Verify" button: this verifies the text box contents against the stored signature, and styles the displayed signature according to the result.</li>
61+
<li>
62+
A "Sign" button: this signs the text box contents, displays part of
63+
the signature, and stores the complete signature.
64+
</li>
65+
<li>
66+
A "Verify" button: this verifies the text box contents against the
67+
stored signature, and styles the displayed signature according to
68+
the result.
69+
</li>
2870
</ul>
2971
<p>Try it:</p>
3072
<ul>
@@ -41,12 +83,19 @@ <h2 class="sign-verify-heading">RSASSA-PKCS1-v1_5</h2>
4183
<section class="sign-verify-controls">
4284
<div class="message-control">
4385
<label for="rsassa-pkcs1-message">Enter a message to sign:</label>
44-
<input type="text" id="rsassa-pkcs1-message" name="message" size="25"
45-
value="The owl hoots at midnight">
86+
<input
87+
type="text"
88+
id="rsassa-pkcs1-message"
89+
name="message"
90+
size="25"
91+
value="The owl hoots at midnight"
92+
/>
4693
</div>
47-
<div class="signature">Signature:<span class="signature-value"></span></div>
48-
<input class="sign-button" type="button" value="Sign">
49-
<input class="verify-button" type="button" value="Verify">
94+
<div class="signature">
95+
Signature:<span class="signature-value"></span>
96+
</div>
97+
<input class="sign-button" type="button" value="Sign" />
98+
<input class="verify-button" type="button" value="Verify" />
5099
</section>
51100
</section>
52101

@@ -55,12 +104,19 @@ <h2 class="sign-verify-heading">RSA-PSS</h2>
55104
<section class="sign-verify-controls">
56105
<div class="message-control">
57106
<label for="rsa-pss-message">Enter a message to sign:</label>
58-
<input type="text" id="rsa-pss-message" name="message" size="25"
59-
value="The tiger prowls at dawn">
107+
<input
108+
type="text"
109+
id="rsa-pss-message"
110+
name="message"
111+
size="25"
112+
value="The tiger prowls at dawn"
113+
/>
114+
</div>
115+
<div class="signature">
116+
Signature:<span class="signature-value"></span>
60117
</div>
61-
<div class="signature">Signature:<span class="signature-value"></span></div>
62-
<input class="sign-button" type="button" value="Sign">
63-
<input class="verify-button" type="button" value="Verify">
118+
<input class="sign-button" type="button" value="Sign" />
119+
<input class="verify-button" type="button" value="Verify" />
64120
</section>
65121
</section>
66122

@@ -69,12 +125,19 @@ <h2 class="sign-verify-heading">ECDSA</h2>
69125
<section class="sign-verify-controls">
70126
<div class="message-control">
71127
<label for="ecdsa-message">Enter a message to sign:</label>
72-
<input type="text" id="ecdsa-message" name="message" size="25"
73-
value="The eagle flies at twilight">
128+
<input
129+
type="text"
130+
id="ecdsa-message"
131+
name="message"
132+
size="25"
133+
value="The eagle flies at twilight"
134+
/>
74135
</div>
75-
<div class="signature">Signature:<span class="signature-value"></span></div>
76-
<input class="sign-button" type="button" value="Sign">
77-
<input class="verify-button" type="button" value="Verify">
136+
<div class="signature">
137+
Signature:<span class="signature-value"></span>
138+
</div>
139+
<input class="sign-button" type="button" value="Sign" />
140+
<input class="verify-button" type="button" value="Verify" />
78141
</section>
79142
</section>
80143

@@ -83,20 +146,48 @@ <h2 class="sign-verify-heading">HMAC</h2>
83146
<section class="sign-verify-controls">
84147
<div class="message-control">
85148
<label for="hmac-message">Enter a message to sign:</label>
86-
<input type="text" id="hmac-message" name="message" size="25"
87-
value="The bunny hops at teatime">
149+
<input
150+
type="text"
151+
id="hmac-message"
152+
name="message"
153+
size="25"
154+
value="The bunny hops at teatime"
155+
/>
156+
</div>
157+
<div class="signature">
158+
Signature:<span class="signature-value"></span>
159+
</div>
160+
<input class="sign-button" type="button" value="Sign" />
161+
<input class="verify-button" type="button" value="Verify" />
162+
</section>
163+
</section>
164+
165+
<section class="sign-verify ed25519">
166+
<h2 class="sign-verify-heading">Ed25519</h2>
167+
<section class="sign-verify-controls">
168+
<div class="message-control">
169+
<label for="ed25519-message">Enter a message to sign:</label>
170+
<input
171+
type="text"
172+
id="ed25519-message"
173+
name="message"
174+
size="25"
175+
value="The lion roars near dawn"
176+
/>
177+
</div>
178+
<div class="signature">
179+
Signature:<span class="signature-value"></span>
88180
</div>
89-
<div class="signature">Signature:<span class="signature-value"></span></div>
90-
<input class="sign-button" type="button" value="Sign">
91-
<input class="verify-button" type="button" value="Verify">
181+
<input class="sign-button" type="button" value="Sign" />
182+
<input class="verify-button" type="button" value="Verify" />
92183
</section>
93184
</section>
94185
</section>
95186
</main>
96-
97187
</body>
98188
<script src="rsassa-pkcs1.js"></script>
99189
<script src="rsa-pss.js"></script>
100190
<script src="ecdsa.js"></script>
101191
<script src="hmac.js"></script>
192+
<script src="ed25519.js"></script>
102193
</html>

0 commit comments

Comments
 (0)