diff --git a/manual.pdf b/manual.pdf index 8a4192d..c16fb56 100644 Binary files a/manual.pdf and b/manual.pdf differ diff --git a/manual.typ b/manual.typ index c1668d3..c955a35 100644 --- a/manual.typ +++ b/manual.typ @@ -13,25 +13,31 @@ ) #tidy.show-module(sha-doc) +#pagebreak(weak: true) + #let md-doc = mod( read("src/md.typ"), name: "md" ) #tidy.show-module(md-doc) +#pagebreak(weak: true) + #let misc-doc = mod( read("src/misc.typ"), name: "misc" ) #tidy.show-module(misc-doc) +#pagebreak(weak: true) + #let base-doc = mod( read("src/base.typ"), name: "base" ) #tidy.show-module(base-doc) -#pagebreak() +#pagebreak(weak: true) #let utils-doc = mod( read("src/utils.typ"), diff --git a/src/misc.typ b/src/misc.typ index e38a3c3..3a9178d 100644 --- a/src/misc.typ +++ b/src/misc.typ @@ -1,5 +1,7 @@ #import "utils.typ": xor-bytes #import "sha.typ": sha1 +#import "md.typ": md4 +#import "utils.typ": utf8-to-utf16le #let _compute-block-sized-key(key, hash-func: sha1, block-size: 64) = { if key.len() > block-size { @@ -45,4 +47,13 @@ let o-key-pad = xor-bytes(key, o-pad) return hash-func(o-key-pad + hash-func(i-key-pad + message)) +} + +/// New Technology LAN Manager (aka. Windows password hash) +/// ```example +/// #bytes-to-hex(ntlm("Bellevue")) +/// ``` +/// -> bytes +#let ntlm(password) = { + return md4(utf8-to-utf16le(password)) } \ No newline at end of file diff --git a/src/utils.typ b/src/utils.typ index 0f05eda..6f22833 100644 --- a/src/utils.typ +++ b/src/utils.typ @@ -116,4 +116,29 @@ let d2 = a return a2.bit-or(b2).bit-or(c2).bit-or(d2) +} + +/// Converts a UTF-8 string to UTF-16LE +/// -> bytes +#let utf8-to-utf16le( + /// -> str + string +) = { + let utf16le-bytes = () + for c in string.codepoints() { + let u = c.to-unicode() + if u <= 0xffff { + utf16le-bytes.push(u.bit-and(0xff)) + utf16le-bytes.push(u.bit-rshift(8)) + } else { + let u2 = u - 0x10000 + let hs = 0xd800 + u2.bit-rshift(10) + let ls = 0xdc00 + u2.bit-and(0x3ff) + utf16le-bytes.push(hs.bit-and(0xff)) + utf16le-bytes.push(hs.bit-rshift(8)) + utf16le-bytes.push(ls.bit-and(0xff)) + utf16le-bytes.push(ls.bit-rshift(8)) + } + } + return bytes(utf16le-bytes) } \ No newline at end of file