Skip to content

Instantly share code, notes, and snippets.

@lf94
Created April 21, 2024 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lf94/12a59242281d9b86679550e184a0c065 to your computer and use it in GitHub Desktop.
Save lf94/12a59242281d9b86679550e184a0c065 to your computer and use it in GitHub Desktop.
\ Here lies a true exercise for my Forth studies.
\ Translated from pseudo-code data:text/plain;base64,Tm90ZSAxOiBBbGwgdmFyaWFibGVzIGFyZSAzMiBiaXQgdW5zaWduZWQgaW50ZWdlcnMgYW5kIGFkZGl0aW9uIGlzIGNhbGN1bGF0ZWQgbW9kdWxvIDIzMgpOb3RlIDI6IEZvciBlYWNoIHJvdW5kLCB0aGVyZSBpcyBvbmUgcm91bmQgY29uc3RhbnQga1tpXSBhbmQgb25lIGVudHJ5IGluIHRoZSBtZXNzYWdlIHNjaGVkdWxlIGFycmF5IHdbaV0sIDAg4omkIGkg4omkIDYzCk5vdGUgMzogVGhlIGNvbXByZXNzaW9uIGZ1bmN0aW9uIHVzZXMgOCB3b3JraW5nIHZhcmlhYmxlcywgYSB0aHJvdWdoIGgKTm90ZSA0OiBCaWctZW5kaWFuIGNvbnZlbnRpb24gaXMgdXNlZCB3aGVuIGV4cHJlc3NpbmcgdGhlIGNvbnN0YW50cyBpbiB0aGlzIHBzZXVkb2NvZGUsCiAgICBhbmQgd2hlbiBwYXJzaW5nIG1lc3NhZ2UgYmxvY2sgZGF0YSBmcm9tIGJ5dGVzIHRvIHdvcmRzLCBmb3IgZXhhbXBsZSwKICAgIHRoZSBmaXJzdCB3b3JkIG9mIHRoZSBpbnB1dCBtZXNzYWdlICJhYmMiIGFmdGVyIHBhZGRpbmcgaXMgMHg2MTYyNjM4MAoKSW5pdGlhbGl6ZSBoYXNoIHZhbHVlczoKKGZpcnN0IDMyIGJpdHMgb2YgdGhlIGZyYWN0aW9uYWwgcGFydHMgb2YgdGhlIHNxdWFyZSByb290cyBvZiB0aGUgZmlyc3QgOCBwcmltZXMgMi4uMTkpOgpoMCA6PSAweDZhMDllNjY3CmgxIDo9IDB4YmI2N2FlODUKaDIgOj0gMHgzYzZlZjM3MgpoMyA6PSAweGE1NGZmNTNhCmg0IDo9IDB4NTEwZTUyN2YKaDUgOj0gMHg5YjA1Njg4YwpoNiA6PSAweDFmODNkOWFiCmg3IDo9IDB4NWJlMGNkMTkKCkluaXRpYWxpemUgYXJyYXkgb2Ygcm91bmQgY29uc3RhbnRzOgooZmlyc3QgMzIgYml0cyBvZiB0aGUgZnJhY3Rpb25hbCBwYXJ0cyBvZiB0aGUgY3ViZSByb290cyBvZiB0aGUgZmlyc3QgNjQgcHJpbWVzIDIuLjMxMSk6CmtbMC4uNjNdIDo9CiAgIDB4NDI4YTJmOTgsIDB4NzEzNzQ0OTEsIDB4YjVjMGZiY2YsIDB4ZTliNWRiYTUsIDB4Mzk1NmMyNWIsIDB4NTlmMTExZjEsIDB4OTIzZjgyYTQsIDB4YWIxYzVlZDUsCiAgIDB4ZDgwN2FhOTgsIDB4MTI4MzViMDEsIDB4MjQzMTg1YmUsIDB4NTUwYzdkYzMsIDB4NzJiZTVkNzQsIDB4ODBkZWIxZmUsIDB4OWJkYzA2YTcsIDB4YzE5YmYxNzQsCiAgIDB4ZTQ5YjY5YzEsIDB4ZWZiZTQ3ODYsIDB4MGZjMTlkYzYsIDB4MjQwY2ExY2MsIDB4MmRlOTJjNmYsIDB4NGE3NDg0YWEsIDB4NWNiMGE5ZGMsIDB4NzZmOTg4ZGEsCiAgIDB4OTgzZTUxNTIsIDB4YTgzMWM2NmQsIDB4YjAwMzI3YzgsIDB4YmY1OTdmYzcsIDB4YzZlMDBiZjMsIDB4ZDVhNzkxNDcsIDB4MDZjYTYzNTEsIDB4MTQyOTI5NjcsCiAgIDB4MjdiNzBhODUsIDB4MmUxYjIxMzgsIDB4NGQyYzZkZmMsIDB4NTMzODBkMTMsIDB4NjUwYTczNTQsIDB4NzY2YTBhYmIsIDB4ODFjMmM5MmUsIDB4OTI3MjJjODUsCiAgIDB4YTJiZmU4YTEsIDB4YTgxYTY2NGIsIDB4YzI0YjhiNzAsIDB4Yzc2YzUxYTMsIDB4ZDE5MmU4MTksIDB4ZDY5OTA2MjQsIDB4ZjQwZTM1ODUsIDB4MTA2YWEwNzAsCiAgIDB4MTlhNGMxMTYsIDB4MWUzNzZjMDgsIDB4Mjc0ODc3NGMsIDB4MzRiMGJjYjUsIDB4MzkxYzBjYjMsIDB4NGVkOGFhNGEsIDB4NWI5Y2NhNGYsIDB4NjgyZTZmZjMsCiAgIDB4NzQ4ZjgyZWUsIDB4NzhhNTYzNmYsIDB4ODRjODc4MTQsIDB4OGNjNzAyMDgsIDB4OTBiZWZmZmEsIDB4YTQ1MDZjZWIsIDB4YmVmOWEzZjcsIDB4YzY3MTc4ZjIKClByZS1wcm9jZXNzaW5nIChQYWRkaW5nKToKYmVnaW4gd2l0aCB0aGUgb3JpZ2luYWwgbWVzc2FnZSBvZiBsZW5ndGggTCBiaXRzCmFwcGVuZCBhIHNpbmdsZSAnMScgYml0CmFwcGVuZCBLICcwJyBiaXRzLCB3aGVyZSBLIGlzIHRoZSBtaW5pbXVtIG51bWJlciA+PSAwIHN1Y2ggdGhhdCAoTCArIDEgKyBLICsgNjQpIGlzIGEgbXVsdGlwbGUgb2YgNTEyCmFwcGVuZCBMIGFzIGEgNjQtYml0IGJpZy1lbmRpYW4gaW50ZWdlciwgbWFraW5nIHRoZSB0b3RhbCBwb3N0LXByb2Nlc3NlZCBsZW5ndGggYSBtdWx0aXBsZSBvZiA1MTIgYml0cwpzdWNoIHRoYXQgdGhlIGJpdHMgaW4gdGhlIG1lc3NhZ2UgYXJlOiA8b3JpZ2luYWwgbWVzc2FnZSBvZiBsZW5ndGggTD4gMSA8SyB6ZXJvcz4gPEwgYXMgNjQgYml0IGludGVnZXI+ICwgKHRoZSBudW1iZXIgb2YgYml0cyB3aWxsIGJlIGEgbXVsdGlwbGUgb2YgNTEyKQoKUHJvY2VzcyB0aGUgbWVzc2FnZSBpbiBzdWNjZXNzaXZlIDUxMi1iaXQgY2h1bmtzOgpicmVhayBtZXNzYWdlIGludG8gNTEyLWJpdCBjaHVua3MKZm9yIGVhY2ggY2h1bmsKICAgIGNyZWF0ZSBhIDY0LWVudHJ5IG1lc3NhZ2Ugc2NoZWR1bGUgYXJyYXkgd1swLi42M10gb2YgMzItYml0IHdvcmRzCiAgICAoVGhlIGluaXRpYWwgdmFsdWVzIGluIHdbMC4uNjNdIGRvbid0IG1hdHRlciwgc28gbWFueSBpbXBsZW1lbnRhdGlvbnMgemVybyB0aGVtIGhlcmUpCiAgICBjb3B5IGNodW5rIGludG8gZmlyc3QgMTYgd29yZHMgd1swLi4xNV0gb2YgdGhlIG1lc3NhZ2Ugc2NoZWR1bGUgYXJyYXkKCiAgICBFeHRlbmQgdGhlIGZpcnN0IDE2IHdvcmRzIGludG8gdGhlIHJlbWFpbmluZyA0OCB3b3JkcyB3WzE2Li42M10gb2YgdGhlIG1lc3NhZ2Ugc2NoZWR1bGUgYXJyYXk6CiAgICBmb3IgaSBmcm9tIDE2IHRvIDYzCiAgICAgICAgczAgOj0gKHdbaS0xNV0gcmlnaHRyb3RhdGUgIDcpIHhvciAod1tpLTE1XSByaWdodHJvdGF0ZSAxOCkgeG9yICh3W2ktMTVdIHJpZ2h0c2hpZnQgIDMpCiAgICAgICAgczEgOj0gKHdbaS0yXSByaWdodHJvdGF0ZSAxNykgeG9yICh3W2ktMl0gcmlnaHRyb3RhdGUgMTkpIHhvciAod1tpLTJdIHJpZ2h0c2hpZnQgMTApCiAgICAgICAgd1tpXSA6PSB3W2ktMTZdICsgczAgKyB3W2ktN10gKyBzMQoKICAgIEluaXRpYWxpemUgd29ya2luZyB2YXJpYWJsZXMgdG8gY3VycmVudCBoYXNoIHZhbHVlOgogICAgYSA6PSBoMAogICAgYiA6PSBoMQogICAgYyA6PSBoMgogICAgZCA6PSBoMwogICAgZSA6PSBoNAogICAgZiA6PSBoNQogICAgZyA6PSBoNgogICAgaCA6PSBoNwoKICAgIENvbXByZXNzaW9uIGZ1bmN0aW9uIG1haW4gbG9vcDoKICAgIGZvciBpIGZyb20gMCB0byA2MwogICAgICAgIFMxIDo9IChlIHJpZ2h0cm90YXRlIDYpIHhvciAoZSByaWdodHJvdGF0ZSAxMSkgeG9yIChlIHJpZ2h0cm90YXRlIDI1KQogICAgICAgIGNoIDo9IChlIGFuZCBmKSB4b3IgKChub3QgZSkgYW5kIGcpCiAgICAgICAgdGVtcDEgOj0gaCArIFMxICsgY2ggKyBrW2ldICsgd1tpXQogICAgICAgIFMwIDo9IChhIHJpZ2h0cm90YXRlIDIpIHhvciAoYSByaWdodHJvdGF0ZSAxMykgeG9yIChhIHJpZ2h0cm90YXRlIDIyKQogICAgICAgIG1haiA6PSAoYSBhbmQgYikgeG9yIChhIGFuZCBjKSB4b3IgKGIgYW5kIGMpCiAgICAgICAgdGVtcDIgOj0gUzAgKyBtYWoKIAogICAgICAgIGggOj0gZwogICAgICAgIGcgOj0gZgogICAgICAgIGYgOj0gZQogICAgICAgIGUgOj0gZCArIHRlbXAxCiAgICAgICAgZCA6PSBjCiAgICAgICAgYyA6PSBiCiAgICAgICAgYiA6PSBhCiAgICAgICAgYSA6PSB0ZW1wMSArIHRlbXAyCgogICAgQWRkIHRoZSBjb21wcmVzc2VkIGNodW5rIHRvIHRoZSBjdXJyZW50IGhhc2ggdmFsdWU6CiAgICBoMCA6PSBoMCArIGEKICAgIGgxIDo9IGgxICsgYgogICAgaDIgOj0gaDIgKyBjCiAgICBoMyA6PSBoMyArIGQKICAgIGg0IDo9IGg0ICsgZQogICAgaDUgOj0gaDUgKyBmCiAgICBoNiA6PSBoNiArIGcKICAgIGg3IDo9IGg3ICsgaAoKUHJvZHVjZSB0aGUgZmluYWwgaGFzaCB2YWx1ZSAoYmlnLWVuZGlhbik6CmRpZ2VzdCA6PSBoYXNoIDo9IGgwIGFwcGVuZCBoMSBhcHBlbmQgaDIgYXBwZW5kIGgzIGFwcGVuZCBoNCBhcHBlbmQgaDUgYXBwZW5kIGg2IGFwcGVuZCBoNw==
\ Use for tests.
: assert= ( a b ) over over <> if .s abort then drop drop ;
\ Return stack operations over lists
: >r.. ( x .. n -- )
r> swap \ We need the return address.
( x ... ret n )
begin dup 0 > while
rot ( x1 x2 n x3 .. ) >r
1 -
repeat drop
>r \ Push the return address back to the return stack
;
: swap.. ( x .. n -- x4 x1 x2 x3 .. )
dup
begin dup 0 > while
>r >r
swap
r> r>
rot
>r
1 -
repeat drop
begin dup 0 > while
r>
swap
1 -
repeat drop
;
1 2 3 4 3 swap..
3 assert=
2 assert=
1 assert=
4 assert=
1 2 3 4 0 swap..
4 assert=
3 assert=
2 assert=
1 assert=
depth 0 assert=
: rev.. ( x .. y n -- y .. x )
1 - >r
begin r@ 0 > while
r@ swap..
r> 1 - >r
repeat r> drop
;
1 2 3 4 4 rev..
1 assert=
2 assert=
3 assert=
4 assert=
depth 0 assert=
: assert=.. ( a b .. n )
dup >r
rev..
r>
dup
begin dup 0 > while
rot >r
1 -
repeat drop
begin dup 0 > while
swap r> assert=
1 -
repeat drop
;
1 2 3 4 4 rev..
4 3 2 1 4 assert=..
depth 0 assert=
: bits 8 / ;
: bytes 8 * ;
: 8! c! ;
: 8@ c@ ;
: 32dup ( a b -- a b a b )
over over
;
: 2cc! ( n1 n2 addr -- )
>r
dup r@ 3 + 8!
8 rshift r@ 2 + 8!
dup r@ 1 + 8!
8 rshift r@ 8!
r>
drop
;
: 4c! ( b1 b2 b3 b4 addr -- )
>r
r@ 3 + 8!
r@ 2 + 8!
r@ 1 + 8!
r@ 8!
r>
drop
;
: 32@ ( addr -- n1 n2 )
>r
r@ 8@ 8 lshift
r@ 1 + 8@ or
r@ 2 + 8@ 8 lshift
r@ 3 + 8@ or
r>
drop
;
create 16a 1 cells allot
create 16b 1 cells allot
create 16c 1 cells allot
create 16d 1 cells allot
: 32rr ( a b n -- )
>r
16b !
16a !
begin r@ 0 > while
16a @ %0000000000000001 and if %1000000000000000 else %0000000000000000 then
16b @ %0000000000000001 and if %1000000000000000 else %0000000000000000 then
16a @ 1 rshift or 16a !
16b @ 1 rshift or 16b !
r> 1 - >r
repeat
r> drop
16a @
16b @
;
\ full rotation
12 34 4 bytes 32rr
12 34 2 assert=..
\ half rotation
$1122 $3344 2 bytes 32rr
$3344 $1122 2 assert=..
\ byte rotation
$1122 $3344 1 bytes 32rr
$4411 $2233 2 assert=..
\ no rotation
12 34 0 bytes 32rr
12 34 2 assert=..
$165D $FFEB 2 32rr
$C597 $7FFA 2 assert=..
\ stack clear
depth 0 assert=
: 32rs ( a b n -- )
>r
16b !
16a !
begin r@ 0 > while
16a @ %0000000000000001 and if %1000000000000000 else %0000000000000000 then
16b @ 1 rshift or 16b !
16a @ 1 rshift 16a !
r> 1 - >r
repeat
r> drop
16a @ 16b @
;
\ full shift
12 34 4 bytes 32rs
00 00 2 assert=..
\ half shift
12 34 2 bytes 32rs
00 12 2 assert=..
\ no shift
12 34 0 bytes 32rs
12 34 2 assert=..
\ stack clear
depth 0 assert=
: 32xor ( a b c d -- e f )
16d !
16c !
16b !
16a !
16a @
16c @
xor
16b @
16d @
xor
;
\ all 1 bits
$4654 $5656 $FFFF $FFFF 32xor
$B9AB $A9A9 2 assert=..
\ all 0 bits
$4654 $5656 $0000 $0000 32xor
$4654 $5656 2 assert=..
depth 0 assert=
: 32and ( a b c d -- e f )
16d !
16c !
16b !
16a !
16a @
16c @
and
16b @
16d @
and
;
\ all 1 bits
$4654 $5656 $FFFF $FFFF 32and
$4654 $5656 2 assert=..
\ all 0 bits
$4654 $5656 $0000 $0000 32and
$0000 $0000 2 assert=..
depth 0 assert=
: 32not ( a b -- c d )
$FFFF xor swap
$FFFF xor swap
;
$0000 $0000 32not
$FFFF $FFFF 2 assert=..
$FFFF $FFFF 32not
$0000 $0000 2 assert=..
depth 0 assert=
: 16+>? ( a b -- n )
65535 swap - > abs
;
: 16+ ( a b -- n )
+ 65536 mod
;
create carry 0 ,
: 32+ ( a b c d -- e f )
>r 16c ! r>
over over 16+>? carry !
16+ >r
16c @
carry @ ( a c carry )
over over 16+>? carry !
16+ ( a k )
over over 16+>? carry @ or carry !
16+ ( f )
r>
;
\ add two 0s
$0000 $0000 $0000 $0000 32+
$0000 $0000 2 assert=..
\ add two 1s
$0000 $0001 $0000 $0001 32+
$0000 $0002 2 assert=..
\ cause carry on first byte
$0000 $00FF $0000 $0001 32+
$0000 $0100 2 assert=..
\ carry over many
$00FF $FFFF $0000 $0001 32+
$0100 $0000 2 assert=..
\ overflow
$FFFF $FFFF $0000 $0001 32+
$0000 $0000 2 assert=..
\ carry caused by last
$00FF $80FF $0000 $7F01 32+
$0100 $0000 2 assert=..
\ carry and not
$00FF $0000 $0080 $0001 32+
$017F $0001 2 assert=..
\ random tests
$0263 $08A9 $13FA $F742 32+
$165D $FFEB 2 assert=..
depth 0 assert=
create K[]
$42 c, $8a c, $2f c, $98 c,
$71 c, $37 c, $44 c, $91 c,
$b5 c, $c0 c, $fb c, $cf c,
$e9 c, $b5 c, $db c, $a5 c,
$39 c, $56 c, $c2 c, $5b c,
$59 c, $f1 c, $11 c, $f1 c,
$92 c, $3f c, $82 c, $a4 c,
$ab c, $1c c, $5e c, $d5 c,
$d8 c, $07 c, $aa c, $98 c,
$12 c, $83 c, $5b c, $01 c,
$24 c, $31 c, $85 c, $be c,
$55 c, $0c c, $7d c, $c3 c,
$72 c, $be c, $5d c, $74 c,
$80 c, $de c, $b1 c, $fe c,
$9b c, $dc c, $06 c, $a7 c,
$c1 c, $9b c, $f1 c, $74 c,
$e4 c, $9b c, $69 c, $c1 c,
$ef c, $be c, $47 c, $86 c,
$0f c, $c1 c, $9d c, $c6 c,
$24 c, $0c c, $a1 c, $cc c,
$2d c, $e9 c, $2c c, $6f c,
$4a c, $74 c, $84 c, $aa c,
$5c c, $b0 c, $a9 c, $dc c,
$76 c, $f9 c, $88 c, $da c,
$98 c, $3e c, $51 c, $52 c,
$a8 c, $31 c, $c6 c, $6d c,
$b0 c, $03 c, $27 c, $c8 c,
$bf c, $59 c, $7f c, $c7 c,
$c6 c, $e0 c, $0b c, $f3 c,
$d5 c, $a7 c, $91 c, $47 c,
$06 c, $ca c, $63 c, $51 c,
$14 c, $29 c, $29 c, $67 c,
$27 c, $b7 c, $0a c, $85 c,
$2e c, $1b c, $21 c, $38 c,
$4d c, $2c c, $6d c, $fc c,
$53 c, $38 c, $0d c, $13 c,
$65 c, $0a c, $73 c, $54 c,
$76 c, $6a c, $0a c, $bb c,
$81 c, $c2 c, $c9 c, $2e c,
$92 c, $72 c, $2c c, $85 c,
$a2 c, $bf c, $e8 c, $a1 c,
$a8 c, $1a c, $66 c, $4b c,
$c2 c, $4b c, $8b c, $70 c,
$c7 c, $6c c, $51 c, $a3 c,
$d1 c, $92 c, $e8 c, $19 c,
$d6 c, $99 c, $06 c, $24 c,
$f4 c, $0e c, $35 c, $85 c,
$10 c, $6a c, $a0 c, $70 c,
$19 c, $a4 c, $c1 c, $16 c,
$1e c, $37 c, $6c c, $08 c,
$27 c, $48 c, $77 c, $4c c,
$34 c, $b0 c, $bc c, $b5 c,
$39 c, $1c c, $0c c, $b3 c,
$4e c, $d8 c, $aa c, $4a c,
$5b c, $9c c, $ca c, $4f c,
$68 c, $2e c, $6f c, $f3 c,
$74 c, $8f c, $82 c, $ee c,
$78 c, $a5 c, $63 c, $6f c,
$84 c, $c8 c, $78 c, $14 c,
$8c c, $c7 c, $02 c, $08 c,
$90 c, $be c, $ff c, $fa c,
$a4 c, $50 c, $6c c, $eb c,
$be c, $f9 c, $a3 c, $f7 c,
$c6 c, $71 c, $78 c, $f2 c,
\ How many of something you need to pad to the target b.
: pad_to ( a b - c ) swap over mod over - abs swap drop ;
3 512 pad_to 512 3 - assert=
3 512 + 512 pad_to 512 3 - assert=
s" hello world" swap drop ( a ) bytes 512 pad_to
512 11 bytes -
assert=
: K_to_pad ( n:bits -- m:bits )
8 + 64 + 512 pad_to
;
s" hello world" swap drop bytes K_to_pad bits 44 assert=
\ Pre-processing (Padding):
\ begin with the original message of length L bits
\ append a single '1' bit
\ append K '0' bits, where K is the minimum number >= 0 such that (L + 1 + K + 64) is a multiple of 512
\ append L as a 64-bit big-endian integer, making the total post-processed length a multiple of 512 bits
\ such that the bits in the message are: <original message of length L> 1 <K zeros> <L as 64 bit integer> , (the number of bits will be a multiple of 512)
: new_512_bits_aligned ( addr n -- addr n )
here >r
\ Calculate the new pre-processed message size
( n )
dup bytes dup K_to_pad +
1 +
7 +
64 +
bits here 1 cells allot ! \ data size (multiple of 512 bits)
here 1 cells + here 1 cells allot ! \ data pointer
dup >r \ message length to append at end
dup bytes K_to_pad bits >r \ calculate K bits to pad with
here swap ( addr here n ) dup allot cmove \ copy original message
%10000000 here 1 allot 8! \ append %10000000 byte
here r> dup allot 0 fill \ append K 0 bits
\ adjust to len cell size
here 7 dup allot 0 fill \ append message length as 64-bit big-endian integer
r> bytes here 1 allot 8! \ the actual length (8-bit)
\ Assert our new message length matches what we calculated
\ here r> - 64 assert=
r@ 1 cells + @
r@ @
r> drop
;
: s0 ( w-addr -- a b c d )
15 32 bits * - >r
r@ 32@ 7 32rr
r@ 32@ 18 32rr
32xor
r@ 32@ 3 32rs
32xor
r> drop
;
: s1 ( w-addr -- a b c d )
2 32 bits * - >r
r@ 32@ 17 32rr
r@ 32@ 19 32rr 32xor
r@ 32@ 10 32rs 32xor
r> drop
;
create w[] 64 32 bits * allot
: part1
16 begin dup 64 < while
>r
r@ 32 bits * w[] + s0
r@ 16 - 32 bits * w[] + 32@ 32+
r@ 32 bits * w[] + s1 32+
r@ 7 - 32 bits * w[] + 32@ 32+
r@ 32 bits * w[] + 2cc!
r> 1 +
repeat drop
;
create h0 32 bits allot
create h1 32 bits allot
create h2 32 bits allot
create h3 32 bits allot
create h4 32 bits allot
create h5 32 bits allot
create h6 32 bits allot
create h7 32 bits allot
create a 32 bits allot
create b 32 bits allot
create c 32 bits allot
create d 32 bits allot
create e 32 bits allot
create f 32 bits allot
create g 32 bits allot
create h 32 bits allot
: z1
e 32@ 6 32rr
e 32@ 11 32rr 32xor
e 32@ 25 32rr 32xor
;
: ch
e 32@ f 32@ 32and
e 32@ 32not g 32@ 32and
32xor
;
: temp1 ( i -- a b c d )
>r
h 32@ z1 32+
ch 32+
K[] r@ 32 bits * + 32@ 32+
w[] r@ 32 bits * + 32@ 32+
r> drop
;
: z0
a 32@ 2 32rr
a 32@ 13 32rr 32xor
a 32@ 22 32rr 32xor
;
: maj
a 32@ b 32@ 32and
a 32@ c 32@ 32and 32xor
b 32@ c 32@ 32and 32xor
;
: temp2 ( -- a b c d )
z0 maj 32+
;
: part2
h0 a 32 bits cmove
h1 b 32 bits cmove
h2 c 32 bits cmove
h3 d 32 bits cmove
h4 e 32 bits cmove
h5 f 32 bits cmove
h6 g 32 bits cmove
h7 h 32 bits cmove
0 begin dup 64 < while
>r
temp2
r@ temp1
32dup d 32@ 32+
g h 32 bits cmove
f g 32 bits cmove
e f 32 bits cmove
( temp1 d 32+ ) e 2cc!
c d 32 bits cmove
b c 32 bits cmove
a b 32 bits cmove
( temp2 temp1 ) 32+ a 2cc!
r> 1 +
repeat drop
;
create message 2 cells allot
: message.length message ;
: message.ptr message 1 cells + ;
\ process 512-bit chunks
: sha256 ( addr n -- 256 bits on stack )
new_512_bits_aligned
message.length !
message.ptr !
$6a $09 $e6 $67 h0 4c!
$bb $67 $ae $85 h1 4c!
$3c $6e $f3 $72 h2 4c!
$a5 $4f $f5 $3a h3 4c!
$51 $0e $52 $7f h4 4c!
$9b $05 $68 $8c h5 4c!
$1f $83 $d9 $ab h6 4c!
$5b $e0 $cd $19 h7 4c!
0 begin dup message.length @ < while
\ copy 16 32-bit words from message[i] to w[0..16]
dup message.ptr @ + w[] 16 32 bits * cmove
part1
part2
h0 32@ a 32@ 32+ h0 2cc!
h1 32@ b 32@ 32+ h1 2cc!
h2 32@ c 32@ 32+ h2 2cc!
h3 32@ d 32@ 32+ h3 2cc!
h4 32@ e 32@ 32+ h4 2cc!
h5 32@ f 32@ 32+ h5 2cc!
h6 32@ g 32@ 32+ h6 2cc!
h7 32@ h 32@ 32+ h7 2cc!
512 bits +
repeat drop
;
s" hello world" sha256
h0 32@ h1 32@ h2 32@ h3 32@ h4 32@ h5 32@ h6 32@ h7 32@
hex .s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment