sign.bend
1# The signature interface.
2#
3# A signature scheme (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 (or seed), refusing
9# a malformed one
10# ~public: SK -> PK its public key
11# ~pk_of: B.Octets -> Result<&2, &2, CrError, PK>
12# a public key from its
13# bytes (CrBadPublicKey)
14# ~pk_to: PK -> B.Octets a public key's bytes
15# ~sign: SK -> B.Octets -> B.Octets the signature of a message
16# ~verify: PK -> B.Octets -> B.Octets -> Bool whether a signature is
17# valid for a message
18# Laws (README.md, "Laws"):
19# accepts verify(public(sk), m, sign(sk, m)) == True, for every secret
20# key and message
21# pk_format pk_of(pk_to(p)) == Done{p}
22# forgery a changed message or signature is refused (tested)
23#
24# No algorithm of bend-osdev is a signature scheme yet; one plugs in by
25# supplying these defs (README.md, "Extension points").
26import Base
27import bend-osdev-bytes@0.1.0.0/bytes.bend as B
28import bend-osdev-crypto@0.1.0.0/crypto.bend as Cr
29
30# A secret key and its public key (open type)
31type CrKeypair<-SK: Data, -PK: Data> is Data:
32 CrKeypair{secret: SK, public: PK}
33
34# The key pair of a secret key's bytes
35def CrSign.keypair(~SK: Data, ~PK: Data, ~secret: B.Octets -> Result<&2, &2, Cr.CrError, SK>, ~public: SK -> PK, o: B.Octets) -> Result<&2, &2, Cr.CrError, CrKeypair<SK, PK>>:
36 Result.map(&2, &2, Cr.CrError, SK, CrKeypair<SK, PK>, +sk => CrKeypair{sk, public(sk)}, secret(o))
37
38def cr.sign.check(~PK: Data, ~verify: PK -> B.Octets -> B.Octets -> Bool, r: Result<&2, &2, Cr.CrError, PK>, m: B.Octets, sig: B.Octets) -> Bool:
39 match r:
40 case Fail{e}:
41 False{}
42 case Done{pk}:
43 verify(pk, m, sig)
44
45# Whether sig is valid for m under the public key with these bytes (False for
46# a malformed key)
47def CrSign.verify_bytes(~PK: Data, ~pk_of: B.Octets -> Result<&2, &2, Cr.CrError, PK>, ~verify: PK -> B.Octets -> B.Octets -> Bool, pk: B.Octets, m: B.Octets, sig: B.Octets) -> Bool:
48 cr.sign.check(~PK, ~verify, pk_of(pk), m, sig)