1 import Base 2 import ./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. 7 def sha256(words: Array, byte_length: Nat) -> Maybe<&1,Array>: 8 Buffer.sha256(words,byte_length) 9 10 def 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 17 def hex_digit(+x: U32) -> Char: 18 hex_digit_if(x, U32.is_lt(x, 10)) 19 20 def 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 27 def 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. 31 def hex_walk(n: Nat, +index: U32, pair: Array & 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 36 def hex(a: Array) -> String: 37 hex_walk(7n,1,Array.get(U32,a,0))