-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.rb
54 lines (46 loc) · 1.36 KB
/
common.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
require 'openssl'
module OpenSSL
# Patch OpenSSL::BN, add integer division
class BN
alias bit_length num_bits
def div(denominator)
(self / denominator)[0]
end
end
end
module Impl
NIST_PRIME =
'ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024' \
'e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd' \
'3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec' \
'6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f' \
'24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361' \
'c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552' \
'bb9ed529077096966d670c354e4abc9804f1746c08ca237327fff' \
'fffffffffffff'.to_i(16)
# Common utils
module Common
def to_i32(value)
value & 0xFFFFFFFF
end
def rot(word, bits)
word = to_i32(word)
to_i32(word << bits | word >> 32 - bits)
end
# Merkle-Damgard padding
def md_pad(length, big_endian: true)
bit_len = length << 3
length = (length + 1) % 64
nb_zeros = 56 - length + (length >= 56 ? 64 : 0)
structure = big_endian ? 'Q>1' : 'Q<1'
[0x80] + [0] * nb_zeros + [bit_len].pack(structure).unpack('C8')
end
end
# Base class for cryptographic hash implementation
class CryptoHashBase
include Impl::Common
def self.hexdigest(*args)
new.digest(*args).unpack('H*').first
end
end
end