Skip to content

Commit

Permalink
Merge branch 'master' into container
Browse files Browse the repository at this point in the history
  • Loading branch information
hanazuki authored Apr 5, 2024
2 parents 088aaec + e7e5448 commit 062eb8b
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 2 deletions.
60 changes: 60 additions & 0 deletions lib/md4.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# https://www.rfc-editor.org/rfc/rfc1320

module MD4
module FixedArith
MASK32 = (1 << 32) - 1

refine Integer do
def rol32(bits)
bits %= 32
(self << bits) & MASK32 | ((self & MASK32) >> (32 - bits))
end

def add32(other)
(self + other) & MASK32
end
end
end

using FixedArith

def self.digest(s)
f = ->(x, y, z) { x & y | ~x & z }
g = ->(x, y, z) { x & y | x & z | y & z }
h = ->(x, y, z) { x ^ y ^ z }

s = s.b + ?\x80.b + ?\x00.b * (64 - (s.bytesize + 1 + 8) % 64) + [s.bytesize * 8].pack('Q<')
a, b, c, d = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476

(0 ... s.bytesize).step(64) do |offset|
x = s.unpack('V16', offset:)
aa, bb, cc, dd = a, b, c, d

[0, 4, 8, 12].each do |k|
a = (a + f.(b, c, d) + x[k ]).rol32( 3)
d = (d + f.(a, b, c) + x[k+ 1]).rol32( 7)
c = (c + f.(d, a, b) + x[k+ 2]).rol32(11)
b = (b + f.(c, d, a) + x[k+ 3]).rol32(19)
end
[0, 1, 2, 3].each do |k|
a = (a + g.(b, c, d) + x[k ] + 0x5a827999).rol32( 3)
d = (d + g.(a, b, c) + x[k+ 4] + 0x5a827999).rol32( 5)
c = (c + g.(d, a, b) + x[k+ 8] + 0x5a827999).rol32( 9)
b = (b + g.(c, d, a) + x[k+12] + 0x5a827999).rol32(13)
end
[0, 2, 1, 3].each do |k|
a = (a + h.(b, c, d) + x[k ] + 0x6ed9eba1).rol32( 3)
d = (d + h.(a, b, c) + x[k+ 8] + 0x6ed9eba1).rol32( 9)
c = (c + h.(d, a, b) + x[k+ 4] + 0x6ed9eba1).rol32(11)
b = (b + h.(c, d, a) + x[k+12] + 0x6ed9eba1).rol32(15)
end
a, b, c, d = a.add32(aa), b.add32(bb), c.add32(cc), d.add32(dd)
end

[a, b, c, d].pack('V4')
end

def self.hexdigest(s)
digest(s).unpack1('H*')
end
end
4 changes: 2 additions & 2 deletions lib/ntlm_hash.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
require 'openssl'
require_relative './md4'

module NtlmHash
def self.ntlm_hash(passwd)
passwd = passwd.encode('UTF-16LE')
OpenSSL::Digest::MD4.hexdigest(passwd).upcase
MD4.hexdigest(passwd).upcase
end
end
22 changes: 22 additions & 0 deletions spec/md4_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require 'md4'

# From RFC1320
TEST_VECTORS = {
'' => '31d6cfe0d16ae931b73c59d7e0c089c0',
'a' => 'bde52cb31de33e46245e05fbdbd6fb24',
'abc' => 'a448017aaf21d8525fc10ae87aa6729d',
'message digest' => 'd9130a8164549fe818874806e1c7014b',
'abcdefghijklmnopqrstuvwxyz' => 'd79e1c308aa5bbcdeea8ed63df412da9',
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' => '043f8582f241db351ce627e153e7f0e4',
'12345678901234567890123456789012345678901234567890123456789012345678901234567890' => 'e33b4ddc9c38f2199c3e7b164fcc0536',
}

RSpec.describe MD4 do
describe '.hexdigest' do
TEST_VECTORS.each do |plain, hash|
example "hexdigest(#{plain})" do
expect(MD4.hexdigest(plain)).to eq hash
end
end
end
end

0 comments on commit 062eb8b

Please sign in to comment.