hash.bend

bend-osdev-crypto@0.1.0.0 · 45 lines · 4 definitions

1# The hash interface.
2#
3# A hash (template arguments, in this order):
4#   ~H: Data                          the state
5#   ~bsize: Nat                       the block size in bytes (HMAC's B)
6#   ~dsize: Nat                       the digest size in bytes (HMAC's L)
7#   ~init: H                          the state before any byte
8#   ~update: H -> B.Octets -> H       the state after more bytes
9#   ~final: H -> B.Octets             the digest of the bytes so far
10#   ~digest: B.Octets -> B.Octets     the digest in one call
11# Laws (README.md, "Laws"):
12#   streaming  update(s, a ++ b) == update(update(s, a), b), for every state
13#              s, so pieces may be fed in any split
14#   split      final(update(update(init, a), b)) == digest(a ++ b): the
15#              streaming result equals the one-shot result for every split
16#   length     final(s) has dsize bytes (tested)
17#
18# A hash whose one-shot form is not separate code takes CrHash.digest_of (the
19# streaming form in one call) as its ~digest. The instances: inst_crc.bend
20# (CRC-32 and CRC-64 of any parameter set, non-cryptographic), inst_sha2.bend
21# (SHA-256, SHA-512), and the hashes package's MD4, MD5, SHA-1, RIPEMD-160,
22# SM3 and Streebog (their defs directly; each file's header gives its tuple).
23# Generic algorithms over any hash: hmac.bend, hkdf.bend.
24import Base
25import bend-osdev-bytes@0.1.0.0/bytes.bend as B
26
27def cr.hash.feed(~H: Data, ~update: H -> B.Octets -> H, ps: List<&2, B.Octets>, s: H) -> H:
28  match ps:
29    case Nil{}:
30      s
31    case Con{p, t}:
32      cr.hash.feed(~H, ~update, t, update(s, p))
33
34# the state after each piece in turn
35def CrHash.update_all(~H: Data, ~update: H -> B.Octets -> H, s: H, ps: List<&2, B.Octets>) -> H:
36  cr.hash.feed(~H, ~update, ps, s)
37
38# the digest of the pieces joined, through the streaming interface
39def CrHash.of_pieces(~H: Data, ~init: H, ~update: H -> B.Octets -> H, ~final: H -> B.Octets, ps: List<&2, B.Octets>) -> B.Octets:
40  final(CrHash.update_all(~H, ~update, init, ps))
41
42# the streaming interface in one call: a ~digest for a hash with no one-shot
43# code of its own
44def CrHash.digest_of(~H: Data, ~init: H, ~update: H -> B.Octets -> H, ~final: H -> B.Octets, m: B.Octets) -> B.Octets:
45  final(update(init, m))