SHA-1 hashing helpers for whole-input and incremental hashing.


sha1

(source -- digest) Computes one SHA-1 digest from a source accepted by toSpan.

ShaCounter

ShaCounter

(-- counter) Creates fresh incremental SHA-1 state for an empty input.
  • Initializes the five-word SHA-1 state, pending byte count zero, and total bit count zero.

Remarks

  • The counter uses fixed In-place storage and defines no INIT, DIE, or allocation-release method.
  • Copying it copies the current hashing state.

Fields

append

(source --) Appends a source chunk to the incremental state.
  • For byte-source requirements, see Accepted sources.
  • Copies input bytes into the pending buffer and transforms every complete 64-byte block. Later changes to the source do not change appended data.

finish

(-- digest) Finalizes the accumulated input and returns its SHA-1 digest.
  • Padding includes the accumulated bit count.
  • finish mutates the chaining state and working buffer. Call it once after the last append; it does not reset the counter, and repeated finish or append-after-finish does not continue the original message correctly. Use a fresh ShaCounter for a new message. To preserve an unfinished state, copy the counter and finish the copy.

Accepted sources

sha1 and ShaCounter.append convert inputs with toSpan.


Digest format

The digest has fresh fixed Nat8 20 array storage; it is not a String, a standard-library Array object, or a view into the input or counter. Bytes are emitted in standard SHA-1 digest order.



Sha1Internal

Sha1Internal

(-- helpers) Provides the public low-level SHA-1 schedule, round, padding, and block-transform operations.

Remarks

  • Sha1Internal is public and callable. It is an implementation helper; callers do not need it for sha1 or ShaCounter.

rol

(value count -- result) Rotates a Nat32 value left by the Nat32 count.

Remarks

  • Use counts 1 through 31 for reliable known and unknown processing. The routine does not validate the count; unknown out-of-range or endpoint counts can reach invalid shifts.

f1

(x y z -- result) Returns (x and (y xor z)) xor z plus 0x5A827999n32, using wrapping Nat32 arithmetic.

f2

(x y z -- result) Returns x xor y xor z plus 0x6ED9EBA1n32, using wrapping Nat32 arithmetic.

f3

(x y z -- result) Returns (x and y) or ((x or y) and z) plus 0x8F1BBCDCn32, using wrapping Nat32 arithmetic.

f4

(x y z -- result) Returns x xor y xor z plus 0xCA62C1D6n32, using wrapping Nat32 arithmetic.

m

(x i -- word) Updates slot i & 15 of a mutable view of a 16-word Nat32 schedule and returns the new word.
  • i is Nat32. The update XORs slots i, i + 2, i + 8, and i + 13 modulo 16, then rotates the result left by one.

r

(a b c d e f word --) Performs one SHA-1 round and updates the supplied registers.
  • b and e must be mutable references to distinct Nat32 registers. Other numeric inputs are Nat32.
  • f consumes three Nat32 values and returns one Nat32 round value through a call boundary. The round writes e + rol(a, 5) + f(b, c, d) + word to e and rotates b left by 30, using wrapping arithmetic.

finish

(count bitSize buffer state -- digest) Pads the pending input and emits a fresh fixed 20-byte digest.
  • count is an Int32 in 0 .. 63; bitSize is Nat64; buffer is a mutable 64-byte Nat8 array; and state is a mutable view of five Nat32 words.
  • State must already represent complete blocks, bitSize is the total pre-padding bit count, and the first count buffer bytes are the remaining tail. The method mutates both buffer and state.
  • The result has fresh fixed Nat8 20 array storage in standard SHA-1 digest order.

transform

(state buffer --) Compresses one 64-byte block into a mutable view of five-word Nat32 state.
  • buffer must support byte indexing at ordinals 0 .. 63. It is read, not retained.

Examples

Incremental and direct hashing agree

The runtime example compares the digest arrays with algorithm's collection = overload; its output is TRUE.

"String"    use
"algorithm" use
"control"   use
"sha1"      use

{} Int32 {} [
  direct: "abc" sha1;
  counter: ShaCounter;
  "ab" @counter.append
  "c" @counter.append
  incremental: @counter.finish;
  (direct incremental = LF) printList
  0
] "main" exportFunction

Expected Output

TRUE

Digest bytes of "abc"

"String"  use
"control" use
"sha1"    use

{} Int32 {} [
  digest: "abc" sha1;
  out: String;

  20 [
    byte: i digest @;
    i 0 > [" " @out.catString] when
    byte 16n8 < ["0" @out.catString] when
    byte @out.catHex
  ] times

  @out.getStringView print
  0
] "main" exportFunction

Expected Output

A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D

See also