kex.bend
1# The key-agreement interface.
2#
3# A key agreement (template arguments, in this order):
4# ~SK: Data a secret key
5# ~PK: Data a public key
6# ~secret: B.Octets -> Result<&2, &2, CrError, SK>
7# a secret key from its
8# bytes, refusing a
9# malformed one
10# ~public: SK -> PK its public key
11# ~pk_of: B.Octets -> Result<&2, &2, CrError, PK>
12# a peer's public key from
13# its bytes (CrBadPublicKey)
14# ~pk_to: PK -> B.Octets a public key's bytes
15# ~shared: SK -> PK -> Result<&2, &2, CrError, B.Octets>
16# the shared secret, or the
17# refusal of a peer key the
18# scheme rejects (CrBadKey)
19# Laws (README.md, "Laws"):
20# agree shared(a, public(b)) == shared(b, public(a)), for every two
21# secret keys: both sides compute the same secret
22# pk_format pk_of(pk_to(p)) == Done{p}
23#
24# No algorithm of bend-osdev is a key agreement yet; one plugs in by
25# supplying these defs (README.md, "Extension points"). A shared secret is
26# keying material for a KDF (kdf.bend), not a key.
27import Base
28import bend-osdev-bytes@0.1.0.0/bytes.bend as B
29import bend-osdev-crypto@0.1.0.0/crypto.bend as Cr
30
31def cr.kex.with(~SK: Data, ~PK: Data, ~shared: SK -> PK -> Result<&2, &2, Cr.CrError, B.Octets>, sk: Result<&2, &2, Cr.CrError, SK>, pk: Result<&2, &2, Cr.CrError, PK>) -> Result<&2, &2, Cr.CrError, B.Octets>:
32 match sk pk:
33 case Fail{e} _:
34 Fail{e}
35 case Done{a} Fail{e}:
36 Fail{e}
37 case Done{a} Done{p}:
38 shared(a, p)
39
40# The shared secret of one's secret key's bytes and the peer's public key's
41# bytes
42def CrKex.agree(~SK: Data, ~PK: Data, ~secret: B.Octets -> Result<&2, &2, Cr.CrError, SK>, ~pk_of: B.Octets -> Result<&2, &2, Cr.CrError, PK>, ~shared: SK -> PK -> Result<&2, &2, Cr.CrError, B.Octets>, sk: B.Octets, peer: B.Octets) -> Result<&2, &2, Cr.CrError, B.Octets>:
43 cr.kex.with(~SK, ~PK, ~shared, secret(sk), pk_of(peer))