src/crypto/sha/packed/sha256.bend

bend-collections-laws-crypto@1.0.0.0 · 37 lines · 7 definitions

1import Base
2import bend-collections-laws-crypto@1.0.0.0/src/crypto/sha/packed/buffer.bend as Buffer
3
4# Sole production hash API. Packed input and output, four bytes per U32,
5# big-endian. Consumes input; returns exactly eight words, or None for an
6# oversized byte length. No byte-list or digest-list compatibility API.
7def sha256(words: Array<U32>, byte_length: Nat) -> Maybe<&1,Array<U32>>:
8  Buffer.sha256(words,byte_length)
9
10def hex_digit_if(x: U32, small: Bool) -> Char:
11  match small:
12    case True{}:
13      Chr{(48 + x : U32)}
14    case False{}:
15      Chr{(87 + x : U32)}
16
17def hex_digit(+x: U32) -> Char:
18  hex_digit_if(x, U32.is_lt(x, 10))
19
20def hex_word_go(n: Nat, +x: U32, acc: String) -> String:
21  match n:
22    case 0n:
23      acc
24    case 1n+p:
25      hex_word_go(p, U32.shrn(x, 4n), SCon{hex_digit((x .&. 15 : U32)), acc})
26
27def hex_word(x: U32) -> String:
28  hex_word_go(8n, x, "")
29
30# Formatting helper consumes eight words; it does not create a digest list.
31def hex_walk(n: Nat, +index: U32, pair: Array<U32> & U32) -> String:
32  match n pair:
33    case 0n Tuple{a,w}: hex_word(w)
34    case 1n+p Tuple{a,w}: hex_word(w) ++ hex_walk(p,U32.inc(index),Array.get(U32,a,index))
35
36def hex(a: Array<U32>) -> String:
37  hex_walk(7n,1,Array.get(U32,a,0))