-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcrypto.knot
More file actions
54 lines (45 loc) · 2.53 KB
/
Copy pathcrypto.knot
File metadata and controls
54 lines (45 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
-- Elliptic curve cryptography demo
(do
-- Key pair generation for encryption (X25519)
keys <- base.generateKeyPair
base.println "Encryption key pair generated"
base.println (" Public key: " ++ base.bytesToHex keys.publicKey)
-- Encrypt is Maybe — Nothing if the public key is unusable (wrong length or
-- a low-order point). Keys often come from a peer, so this is a value to
-- handle, not a crash.
with { message (base.textToBytes "Hello, cryptography!") } (do
encrypted <- base.encrypt keys.publicKey message
case encrypted of
Maybe.Nothing {} -> base.println " Encryption failed: bad public key"
Maybe.Just { value ciphertext } -> do
base.println (" Ciphertext: " ++ base.bytesToHex ciphertext)
-- Decrypt is Maybe too — Nothing on a wrong key or tampered ciphertext.
case base.decrypt keys.privateKey ciphertext of
Maybe.Nothing {} -> base.println " Decryption failed: wrong key or tampered ciphertext"
Maybe.Just { value decrypted } -> case base.bytesToText decrypted of
Maybe.Just t -> base.println (" Decrypted: " ++ t.value)
Maybe.Nothing -> base.println " Decrypted: <invalid utf-8>"
-- Tampering with the ciphertext is caught by the authentication tag.
with { tampered (base.bytesConcat (base.bytesSlice 0 40 ciphertext) (base.textToBytes "XXXX")) } (do
case base.decrypt keys.privateKey tampered of
Maybe.Nothing {} -> base.println " Tampered ciphertext rejected"
Maybe.Just { value _ } -> base.println " BUG: tampered ciphertext decrypted"
yield {})
-- Signing key pair generation (Ed25519)
sigKeys <- base.generateSigningKeyPair
base.println "Signing key pair generated"
base.println (" Public key: " ++ base.bytesToHex sigKeys.publicKey)
-- Sign is Maybe — Nothing if the private key is not 32 bytes.
case base.sign sigKeys.privateKey message of
Maybe.Nothing {} -> base.println " Signing failed: bad private key"
Maybe.Just { value sig } -> do
base.println (" Signature: " ++ base.bytesToHex sig)
with { valid (base.verify sigKeys.publicKey message sig) } (do
base.println (" Valid: " ++ base.show valid)
-- Verify with wrong message should fail
with { wrongMsg (base.textToBytes "Wrong message") } (do
with { invalid (base.verify sigKeys.publicKey wrongMsg sig) } (do
base.println (" Invalid (wrong msg): " ++ base.show invalid)
yield {})))
yield {})
)