Copy script and save it with a .rb extension. Then, open Terminal, and enter:
cd ~/your_path/your_script_folder ruby script_name.rb

# -----
# Input
# -----
# defaults
numbers =
[0b01000000000000001111111111111111,
0b01000000000000000000000000000000,
0b01000000000000000000000000000000,
0b01000000000000000000000000000000,
0b01000000000000000000000000000000,
]
# arguments passed
if ARGV.size >= 2
numbers = ARGV.map {|x| x.to_i(2)} # convert binary strings to integers
end
# ---------
# Animation
# ---------
total = numbers.inject(:+)
width = total.to_s(2).size
(numbers.size + 1).times do |i|
system "clear"
numbers.each.with_index do |x, j|
print ("%032b" % x).rjust(width, " ")
if j > 0
if j <= i
print " +"
end
end
print "\n"
end
puts "--------------------------------".rjust(width, " ")
if i == 0
puts "" # numbers[0].to_s(2).rjust(32, "0").rjust(width, " ")
elsif i < numbers.size # for each addition
puts numbers[0..i].inject(:+).to_s(2).rjust(32, "0").rjust(width, " ")
sleep 0.4 if i == numbers.size-1 # slight delay before the modulus function
else
puts (numbers[0..i].inject(:+) % 2**32).to_s(2).rjust(32, "0").rjust(width, " ") + " mod 2**32"
end
sleep 0.4
end
sleep 1.0

require_relative "sha256lib.rb"
# -------
# Default
# -------
if !defined? $input
# default
$input = "abc"
$message = $input.unpack("B*")[0]
# argument passed
$message = ARGV[0] if ARGV[0] # accept binary message string
# calculate padded message
$padded = padding($message)
end
# --------------
# Message Blocks
# --------------
$blocks = split($padded, 512)
# ---------
# Animation
# ---------
system "clear"
puts $state + "\n" if defined? $state
puts "--------------"
puts "message blocks:"
puts "--------------"
delay(:normal)
system "clear"
puts $state + "\n" if defined? $state
puts "--------------"
puts "message blocks:"
puts "--------------"
$blocks.each.with_index do |block, i|
puts "#{i}: #{block}"
delay(:normal)
end
delay(:slow)
# Save Final State
contents = "" # contruct string with each block so we can use it inside the final frame
$blocks.each.with_index do |block, i|
contents << "#{i}: #{block}"
contents << "\n" if i < $blocks.size - 1 # do not add extra new line after last block
end
$state = <<-FRAME
#{$state}
--------------
message blocks:
--------------
#{contents}
FRAME

# coding: utf-8
require_relative "sha256lib.rb"
# ------
# Choice
# ------
# Ch(x, y, z) = (x & y) ^ (~x & z)
#
# For each x bit:
# * If x is 1 choose y
# * If x is 0 choose z
# -----
# Input
# -----
# defaults
x = 0b00000000111111110000000011111111 # 0x428a2f98
y = 0b00000000000000001111111111111111 # 0x71374491
z = 0b11111111111111110000000000000000 # 0xb5c0fbcf
# arguments passed
if ARGV.size == 3
x = ARGV[0].to_i(2)
y = ARGV[1].to_i(2)
z = ARGV[2].to_i(2)
end
# ---------
# Animation
# ---------
32.downto(1) do |i|
system "clear"
puts "▼".rjust(i+3, " ")
puts "x: #{bits(x)}" #{bits(x)[i-1]}
puts "y: #{bits(y)} #{bits(x)[i-1] == '1' ? '◄' : ''}"
puts "z: #{bits(z)} #{bits(x)[i-1] == '1' ? '' : '◄'}"
puts " #{'-'*32}"
puts bits( (x & y) ^ (~x & z) )[i-1..-1].rjust(35, " ")
sleep(0.1)
end
sleep 1

# coding: utf-8
require_relative "sha256lib.rb"
# -------
# Default
# -------
if !defined? $input
$input = "abc"
$message = $input.unpack("B*")[0] # 011000010110001001100011
$padded = padding($message)
$blocks = split($padded, 512)
# message block
$block_number = 0 # message block number
$block = $blocks[$block_number]
# arguments passed
if ARGV[0] # message block
$block = ARGV[0].rjust(512, "0") # accept binary string as message block
end
# message schedule
$schedule = calculate_schedule($block)
end
# Starting Hash Values - Use Initital Hash Values or hash values from previous compression
if $block_number == 0
initial = IV # Use initial hash values
$hash = initial.clone # Set the initial hash values
else
initial = $hash.clone # Use the result of the previous compression
end
# Schedule (Wt)
w = $schedule
# Constants (Kt)
k = K
# --------
# Settings
# --------
indent = " " * 2
# ---------
# Animation
# ---------
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number})"
puts "#{indent}-----------"
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts
puts
puts
puts
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts
puts
puts
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:slowest)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
t1 = add(w[0], k[0], usigma1($hash[4]), ch($hash[4], $hash[5], $hash[6]), $hash[7])
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
t2 = add(usigma0($hash[0]), maj($hash[0], $hash[1], $hash[2]))
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:slowest)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = #{bits($hash[0])} ↓"
puts "#{indent}b = #{bits($hash[1])} ↓"
puts "#{indent}c = #{bits($hash[2])} ↓"
puts "#{indent}d = #{bits($hash[3])} ↓"
puts "#{indent}e = #{bits($hash[4])} ↓"
puts "#{indent}f = #{bits($hash[5])} ↓"
puts "#{indent}g = #{bits($hash[6])} ↓"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start - Rotate Register Upwards
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = "
puts "#{indent}b = #{bits($hash[0])} ↓"
puts "#{indent}c = #{bits($hash[1])} ↓"
puts "#{indent}d = #{bits($hash[2])} ↓"
puts "#{indent}e = #{bits($hash[3])} ↓"
puts "#{indent}f = #{bits($hash[4])} ↓"
puts "#{indent}g = #{bits($hash[5])} ↓"
puts "#{indent}h = #{bits($hash[6])} ↓"
delay(:normal)
# Start - a is T1 + T2
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = <- T1 + T2"
puts "#{indent}b = #{bits($hash[0])}"
puts "#{indent}c = #{bits($hash[1])}"
puts "#{indent}d = #{bits($hash[2])}"
puts "#{indent}e = #{bits($hash[3])}"
puts "#{indent}f = #{bits($hash[4])}"
puts "#{indent}g = #{bits($hash[5])}"
puts "#{indent}h = #{bits($hash[6])}"
delay(:normal)
# Start - a is T1 + T2
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = #{bits(add(t1, t2))} <- T1 + T2"
puts "#{indent}b = #{bits($hash[0])}"
puts "#{indent}c = #{bits($hash[1])}"
puts "#{indent}d = #{bits($hash[2])}"
puts "#{indent}e = #{bits($hash[3])}"
puts "#{indent}f = #{bits($hash[4])}"
puts "#{indent}g = #{bits($hash[5])}"
puts "#{indent}h = #{bits($hash[6])}"
delay(:normal)
# Start - Add T1 to e
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = #{bits(add(t1, t2))} <- T1 + T2"
puts "#{indent}b = #{bits($hash[0])}"
puts "#{indent}c = #{bits($hash[1])}"
puts "#{indent}d = #{bits($hash[2])}"
puts "#{indent}e = #{bits($hash[3])} + T1"
puts "#{indent}f = #{bits($hash[4])}"
puts "#{indent}g = #{bits($hash[5])}"
puts "#{indent}h = #{bits($hash[6])}"
delay(:normal)
# Start - Add T1 to e
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = #{bits(add(t1, t2))} <- T1 + T2"
puts "#{indent}b = #{bits($hash[0])}"
puts "#{indent}c = #{bits($hash[1])}"
puts "#{indent}d = #{bits($hash[2])}"
puts "#{indent}e = #{bits(add($hash[3], t1))} + T1"
puts "#{indent}f = #{bits($hash[4])}"
puts "#{indent}g = #{bits($hash[5])}"
puts "#{indent}h = #{bits($hash[6])}"
delay(:slowest)
# Apply Changes
$hash[7] = $hash[6]
$hash[6] = $hash[5]
$hash[5] = $hash[4]
$hash[4] = $hash[3]
$hash[3] = $hash[2]
$hash[2] = $hash[1]
$hash[1] = $hash[0]
$hash[0] = ""
$hash[4] = add($hash[4], t1)
$hash[0] = add(t1, t2)
# -------------------
# Remaining Animation
# -------------------
1.upto(63) do |i|
# T1 = h + Σ1(e) + Ch(e, f, g) + Kt + Wt
t1 = add(w[i], k[i], usigma1($hash[4]), ch($hash[4], $hash[5], $hash[6]), $hash[7])
# T2 = Σ0(a) + Maj(a, b, c)
t2 = add(usigma0($hash[0]), maj($hash[0], $hash[1], $hash[2]))
# Frame - T1, T2
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W#{i} = #{bits(w[i])} (message schedule)"
puts "#{indent}K#{i} = #{bits(k[i])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K#{i.to_s.ljust(2, " ")} + W#{i.to_s.ljust(2, " ")} = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = #{bits($hash[0])} <- T1 + T2"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} + T1"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
# Frame - Shift Up
$hash[7] = $hash[6]
$hash[6] = $hash[5]
$hash[5] = $hash[4]
$hash[4] = $hash[3]
$hash[3] = $hash[2]
$hash[2] = $hash[1]
$hash[1] = $hash[0]
$hash[0] = ""
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W#{i} = #{bits(w[i])} (message schedule)"
puts "#{indent}K#{i} = #{bits(k[i])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K#{i.to_s.ljust(2, " ")} + W#{i.to_s.ljust(2, " ")} = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = <- T1 + T2"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} + T1"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
# Frame - Update e and a
$hash[4] = ($hash[4] + t1) % 2 ** 32
$hash[0] = (t1 + t2) % 2 ** 32
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}W#{i} = #{bits(w[i])} (message schedule)"
puts "#{indent}K#{i} = #{bits(k[i])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K#{i.to_s.ljust(2, " ")} + W#{i.to_s.ljust(2, " ")} = #{bits(t1)}"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = #{bits($hash[0])} <- T1 + T2"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} + T1"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
end
delay(:slowest)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts
puts
puts
puts
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts
puts
puts
puts
puts
puts
puts "#{indent}a = #{" " * 32} #{bits($hash[0])}"
puts "#{indent}b = #{" " * 32} #{bits($hash[1])}"
puts "#{indent}c = #{" " * 32} #{bits($hash[2])}"
puts "#{indent}d = #{" " * 32} #{bits($hash[3])}"
puts "#{indent}e = #{" " * 32} #{bits($hash[4])}"
puts "#{indent}f = #{" " * 32} #{bits($hash[5])}"
puts "#{indent}g = #{" " * 32} #{bits($hash[6])}"
puts "#{indent}h = #{" " * 32} #{bits($hash[7])}"
delay(:normal)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts
puts
puts
puts
puts
puts "#{indent} H#{$block_number}:"
puts "#{indent}a = #{bits(initial[0])} #{bits($hash[0])}"
puts "#{indent}b = #{bits(initial[1])} #{bits($hash[1])}"
puts "#{indent}c = #{bits(initial[2])} #{bits($hash[2])}"
puts "#{indent}d = #{bits(initial[3])} #{bits($hash[3])}"
puts "#{indent}e = #{bits(initial[4])} #{bits($hash[4])}"
puts "#{indent}f = #{bits(initial[5])} #{bits($hash[5])}"
puts "#{indent}g = #{bits(initial[6])} #{bits($hash[6])}"
puts "#{indent}h = #{bits(initial[7])} #{bits($hash[7])}"
delay(:normal)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts
puts
puts
puts
puts
puts "#{indent} H#{$block_number}:"
puts "#{indent}a = #{bits(initial[0])} + #{bits($hash[0])}"
puts "#{indent}b = #{bits(initial[1])} + #{bits($hash[1])}"
puts "#{indent}c = #{bits(initial[2])} + #{bits($hash[2])}"
puts "#{indent}d = #{bits(initial[3])} + #{bits($hash[3])}"
puts "#{indent}e = #{bits(initial[4])} + #{bits($hash[4])}"
puts "#{indent}f = #{bits(initial[5])} + #{bits($hash[5])}"
puts "#{indent}g = #{bits(initial[6])} + #{bits($hash[6])}"
puts "#{indent}h = #{bits(initial[7])} + #{bits($hash[7])}"
delay(:slow)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number} -> H#{$block_number+1})"
puts "#{indent}-----------"
puts
puts
puts
puts
puts
puts "#{indent} H#{$block_number+1}:"
puts "#{indent}a = #{bits(add(initial[0], $hash[0]))}"
puts "#{indent}b = #{bits(add(initial[1], $hash[1]))}"
puts "#{indent}c = #{bits(add(initial[2], $hash[2]))}"
puts "#{indent}d = #{bits(add(initial[3], $hash[3]))}"
puts "#{indent}e = #{bits(add(initial[4], $hash[4]))}"
puts "#{indent}f = #{bits(add(initial[5], $hash[5]))}"
puts "#{indent}g = #{bits(add(initial[6], $hash[6]))}"
puts "#{indent}h = #{bits(add(initial[7], $hash[7]))}"
delay(:slow)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H#{$block_number+1})"
puts "#{indent}-----------"
puts "#{indent}a = #{bits(add(initial[0], $hash[0]))}"
puts "#{indent}b = #{bits(add(initial[1], $hash[1]))}"
puts "#{indent}c = #{bits(add(initial[2], $hash[2]))}"
puts "#{indent}d = #{bits(add(initial[3], $hash[3]))}"
puts "#{indent}e = #{bits(add(initial[4], $hash[4]))}"
puts "#{indent}f = #{bits(add(initial[5], $hash[5]))}"
puts "#{indent}g = #{bits(add(initial[6], $hash[6]))}"
puts "#{indent}h = #{bits(add(initial[7], $hash[7]))}"
delay(:end)
$hash[0] = add(initial[0], $hash[0])
$hash[1] = add(initial[1], $hash[1])
$hash[2] = add(initial[2], $hash[2])
$hash[3] = add(initial[3], $hash[3])
$hash[4] = add(initial[4], $hash[4])
$hash[5] = add(initial[5], $hash[5])
$hash[6] = add(initial[6], $hash[6])
$hash[7] = add(initial[7], $hash[7])
# Save Final State
$state = <<-FRAME
#{$state}
#{indent}-----------
#{indent}compression: (H#{$block_number+1})
#{indent}-----------
#{indent}a = #{bits($hash[0])}
#{indent}b = #{bits($hash[1])}
#{indent}c = #{bits($hash[2])}
#{indent}d = #{bits($hash[3])}
#{indent}e = #{bits($hash[4])}
#{indent}f = #{bits($hash[5])}
#{indent}g = #{bits($hash[6])}
#{indent}h = #{bits($hash[7])}
FRAME

# coding: utf-8
require_relative "sha256lib.rb"
# ---------
# Constants - K
# ---------
# SHA256 uses the same sequence of sixty-four constant 32-bit words.
#
# These words represent the first thirty-two bits of the fractional parts of the cube roots of the first sixty-four prime numbers. These are "nothing up my sleeve" constants.
# The first sixty-four primes
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311]
# Store results for display later
roots = [];
constants = [];
hexs = [];
# For each prime number
primes.each do |prime|
# Get the cube root of the prime
root = prime ** (1/3.0)
roots << root
# Get fractional part of the number
fractional = root - root.floor
# Convert fractional part to hexadecimal
#
# Example:
#
# 3√2 = 1.259921049895
# 0.259921049895 <- fractional part is what we want
#
# Keep multiplying the fractional part by 16 and taking the integer as the next hex character.
#
# 0.259921049895 * 16 <- multiply by 16
# = 4.15873679832 <- the integer part is used for the hexadecimal result
#
# 0.15873679832 * 16
# = 2.53978877312
#
# 0.53978877312 * 16
# = 8.63662036992
#
# ...
#
# Hex: 428a2f98
#
hex = ""
8.times do # 32 bits = 8 hex characters
product = fractional * 16 # multiply fraction by 16
carry = product.floor # the integer part of the product is used for the next hexadecimal character
fractional = product - product.floor # the fractional part of the product is used for next round
hex << carry.to_s(16)
end
# Save results
hexs << hex
constants << hex.to_i(16)
end
# ---------
# Animation
# ---------
system "clear"
puts "-------------"
puts "constants (K)"
puts "-------------"
sleep 0.1
(64+1+3).times do |i| # extra 3 iterations to see through
system "clear"
puts "-------------"
puts "constants (K)"
puts "-------------"
i.times do |j|
# 3 or more behind
if j <= i-4
puts "#{j.to_s.ljust(2, " ")} = #{bits(constants[j])}"
end
# 2 behind
if j == i-3
puts "#{j.to_s.ljust(2, " ")} = 3√#{primes[j].to_s.ljust(3, " ")} = #{bits(constants[j])}"
end
# 1 behind
if j == i-2
puts "#{j.to_s.ljust(2, " ")} = 3√#{primes[j].to_s.ljust(3, " ")} = #{(roots[j] - roots[j].floor).to_s[2..-1]}"
end
# current
if j == i-1
puts "#{j.to_s.ljust(2, " ")} = 3√#{primes[j].to_s.ljust(3, " ")} = #{roots[j]}"
end
# dont try and show trailing 64, 65, 66 (this is just to format last 3)
break if j >= 63
end
sleep 0.1
end
sleep 1

# coding: utf-8
require_relative "sha256lib.rb"
# -------
# Default
# -------
if !defined? $input
# default
$input = "abc"
$message = $input.unpack("B*")[0] # 011000010110001001100011
$padded = padding($message)
$blocks = split($padded, 512)
$block_number = 0 # message block number
$block = $blocks[$block_number]
$t = 63 # the word in the message schedule we want to calculate
# arguments passed
if ARGV[0] # message block
$block = ARGV[0].rjust(512, "0") # accept binary string as message block
end
if ARGV[1] # word number
$t = ARGV[1].to_i # choose a word in the message schedule to calculate (16-63)
end
end
# The message block provides the first 16 words for the message schedule (512 bits / 32 bits = 16 words)
$schedule = $block.scan(/.{32}/).map { |w| w.to_i(2) } # convert from binary string to integer for calculations
# Calculate remaining 48 words
16.upto(63) do |i|
$schedule << add(sigma1($schedule[i - 2]), $schedule[i - 7], sigma0($schedule[i - 15]), $schedule[i - 16])
end
# convenient variables for word numbers in the schedule
t = ($t-0).to_s.ljust(2, " ")
t_1 = ($t-1).to_s.ljust(2, " ")
t_2 = ($t-2).to_s.ljust(2, " ")
t_3 = ($t-3).to_s.ljust(2, " ")
t_4 = ($t-4).to_s.ljust(2, " ")
t_5 = ($t-5).to_s.ljust(2, " ")
t_6 = ($t-6).to_s.ljust(2, " ")
t_7 = ($t-7).to_s.ljust(2, " ")
t_8 = ($t-8).to_s.ljust(2, " ")
t_9 = ($t-9).to_s.ljust(2, " ")
t_10 = ($t-10).to_s.ljust(2, " ")
t_11 = ($t-11).to_s.ljust(2, " ")
t_12 = ($t-12).to_s.ljust(2, " ")
t_13 = ($t-13).to_s.ljust(2, " ")
t_14 = ($t-14).to_s.ljust(2, " ")
t_15 = ($t-15).to_s.ljust(2, " ")
t_16 = ($t-16).to_s.ljust(2, " ")
# --------
# Settings
# --------
indent = " " * 2
# ---------
# Animation
# ---------
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])}
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) }
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])}
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) }
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits($schedule[$t-15])} ROTR 7
#{indent}W#{t_14} #{bits($schedule[$t-14])} #{bits($schedule[$t-15])} ROTR 18
#{indent}W#{t_13} #{bits($schedule[$t-13])} #{bits($schedule[$t-15])} SHR 3
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) }
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
7.times do |i|
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(rotr(i + 1, $schedule[$t-15]))} ROTR 7
#{indent}W#{t_14} #{bits($schedule[$t-14])} #{bits($schedule[$t-15])} ROTR 18
#{indent}W#{t_13} #{bits($schedule[$t-13])} #{bits($schedule[$t-15])} SHR 3
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) }
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:fastest)
end
delay(:normal)
# Frame
18.times do |i|
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(rotr(7, $schedule[$t-15]))} ROTR 7
#{indent}W#{t_14} #{bits($schedule[$t-14])} #{bits(rotr(i + 1, $schedule[$t-15]))} ROTR 18
#{indent}W#{t_13} #{bits($schedule[$t-13])} #{bits($schedule[$t-15])} SHR 3
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) }
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:fastest)
end
delay(:normal)
# Frame
3.times do |i|
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(rotr(7, $schedule[$t-15]))} ROTR 7
#{indent}W#{t_14} #{bits($schedule[$t-14])} #{bits(rotr(18, $schedule[$t-15]))} ROTR 18
#{indent}W#{t_13} #{bits($schedule[$t-13])} #{bits(shr(i + 1, $schedule[$t-15]))} SHR 3
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) }
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:fastest)
end
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(rotr(7, $schedule[$t-15]))} ROTR 7
#{indent}W#{t_14} #{bits($schedule[$t-14])} #{bits(rotr(18, $schedule[$t-15]))} ROTR 18
#{indent}W#{t_13} #{bits($schedule[$t-13])} #{bits(shr(3, $schedule[$t-15]))} XOR
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) }
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(rotr(7, $schedule[$t-15]))}
#{indent}W#{t_14} #{bits($schedule[$t-14])} #{bits(rotr(18, $schedule[$t-15]) ^ shr(3, $schedule[$t-15]))} XOR
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) }
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(rotr(7, $schedule[$t-15]) ^ rotr(18, $schedule[$t-15]) ^ shr(3, $schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) }
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(sigma0($schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) } -> #{bits($schedule[$t-7])}
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) }
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(sigma0($schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) } -> #{bits($schedule[$t-7])}
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) } #{bits($schedule[$t-2])} ROTR 17
#{indent}W#{t_3 } #{bits($schedule[$t-3]) } #{bits($schedule[$t-2])} ROTR 19
#{indent}W#{t_2 } #{bits($schedule[$t-2]) } -> #{bits($schedule[$t-2])} SHR 10
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
17.times do |i|
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(sigma0($schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) } -> #{bits($schedule[$t-7])}
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) } #{bits(rotr(i + 1, $schedule[$t-2]))} ROTR 17
#{indent}W#{t_3 } #{bits($schedule[$t-3]) } #{bits($schedule[$t-2])} ROTR 19
#{indent}W#{t_2 } #{bits($schedule[$t-2]) } -> #{bits($schedule[$t-2])} SHR 10
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:fastest)
end
delay(:normal)
# Frame
19.times do |i|
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(sigma0($schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) } -> #{bits($schedule[$t-7])}
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) } #{bits(rotr(17, $schedule[$t-2]))} ROTR 17
#{indent}W#{t_3 } #{bits($schedule[$t-3]) } #{bits(rotr(i + 1, $schedule[$t-2]))} ROTR 19
#{indent}W#{t_2 } #{bits($schedule[$t-2]) } -> #{bits($schedule[$t-2])} SHR 10
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:fastest)
end
delay(:normal)
# Frame
10.times do |i|
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(sigma0($schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) } -> #{bits($schedule[$t-7])}
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) } #{bits(rotr(17, $schedule[$t-2]))} ROTR 17
#{indent}W#{t_3 } #{bits($schedule[$t-3]) } #{bits(rotr(19, $schedule[$t-2]))} ROTR 19
#{indent}W#{t_2 } #{bits($schedule[$t-2]) } -> #{bits(shr(i + 1, $schedule[$t-2]))} SHR 10
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:fastest)
end
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(sigma0($schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) } -> #{bits($schedule[$t-7])}
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) } #{bits(rotr(17, $schedule[$t-2]))} XOR
#{indent}W#{t_3 } #{bits($schedule[$t-3]) } #{bits(rotr(19, $schedule[$t-2]))}
#{indent}W#{t_2 } #{bits($schedule[$t-2]) } -> #{bits(shr(10, $schedule[$t-2]))}
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(sigma0($schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) } -> #{bits($schedule[$t-7])}
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) } #{bits(rotr(19, $schedule[$t-2]) ^ rotr(17, $schedule[$t-2]))} XOR
#{indent}W#{t_2 } #{bits($schedule[$t-2]) } -> #{bits(shr(10, $schedule[$t-2]))}
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:normal)
# Frame
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(sigma0($schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) } -> #{bits($schedule[$t-7])}
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) } -> #{bits(rotr(19, $schedule[$t-2]) ^ rotr(17, $schedule[$t-2]) ^ shr(10, $schedule[$t-2]))} σ1
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:slow)
# Frame
result = add(sigma1($schedule[$t-2]), $schedule[$t-7], sigma0($schedule[$t-15]), $schedule[$t-16])
system "clear"
puts <<-MS
#{indent}----------------
#{indent}message schedule: (expansion)
#{indent}----------------
#{indent}W#{t_16} #{bits($schedule[$t-16])} -> #{bits($schedule[$t-16])}
#{indent}W#{t_15} #{bits($schedule[$t-15])} -> #{bits(sigma0($schedule[$t-15]))} σ0
#{indent}W#{t_14} #{bits($schedule[$t-14])}
#{indent}W#{t_13} #{bits($schedule[$t-13])}
#{indent}W#{t_12} #{bits($schedule[$t-12])}
#{indent}W#{t_11} #{bits($schedule[$t-11])}
#{indent}W#{t_10} #{bits($schedule[$t-10])}
#{indent}W#{t_9 } #{bits($schedule[$t-9]) }
#{indent}W#{t_8 } #{bits($schedule[$t-8]) }
#{indent}W#{t_7 } #{bits($schedule[$t-7]) } -> #{bits($schedule[$t-7])}
#{indent}W#{t_6 } #{bits($schedule[$t-6]) }
#{indent}W#{t_5 } #{bits($schedule[$t-5]) }
#{indent}W#{t_4 } #{bits($schedule[$t-4]) }
#{indent}W#{t_3 } #{bits($schedule[$t-3]) }
#{indent}W#{t_2 } #{bits($schedule[$t-2]) } -> #{bits(sigma1($schedule[$t-2]))} σ1
#{indent}W#{t_1 } #{bits($schedule[$t-1]) }
#{indent}W#{t } #{bits(result)} = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)
MS
delay(:end)
# Spare Frame
# system "clear"
# puts <<-MS
# 47 00000110010111000100001111011010 -> 00000110010111000100001111011010
# 48 11111011001111101000100111001011 -> 11111011001111101000100111001011 ROTR 7
# 49 11001100011101100001011111011011 11111011001111101000100111001011 ROTR 18
# 50 10111001111001100110110000110100 11111011001111101000100111001011 SHR 3
# 51 10101001100110010011011001100111
# 52 10000100101110101101111011011101
# 53 11000010000101000110001010111100
# 54 00010100100001110100011100101100
# 55 10110010000011110111101010011001
# 56 11101111010101111011100111001101 -> 11101111010101111011100111001101
# 57 11101011111001101011001000111000
# 58 10011111111000110000100101011110
# 59 01111000101111001000110101001011
# 60 10100100001111111100111100010101
# 61 01100110100010110010111111111000 -> 01100110100010110010111111111000 ROTR 17
# 62 11101110101010111010001011001100 01100110100010110010111111111000 ROTR 19
# 63 01100110100010110010111111111000 SHR 10
# MS
# sleep 0.2

# coding: utf-8
require_relative "sha256lib.rb"
# -------
# Default
# -------
if !defined? $input
# default
$input = "abc"
# argument passed
$input = ARGV[0] if ARGV[0] # only accept strings for now
$message = $input.unpack("B*")[0] # 011000010110001001100011
$padded = padding($message)
$blocks = split($padded, 512)
# Set initial hash state using initial hash values
$hash = IV
# For each message block
$blocks.each do |block|
# Prepare 64 word message schedule
schedule = calculate_schedule(block)
# Remember starting hash values
initial = $hash.clone
# Apply compression function to update hash values
$hash = compression(initial, schedule, constants = K)
end
end
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "----------------"
puts "final hash value: (H#{$blocks.size})"
puts "----------------"
registers = ("a".."h").to_a
8.times do |i|
puts "#{registers[i]} = #{bits($hash[i])}"
end
delay(:slowest)
# Frame - Hexadecimal
system "clear"
puts $state + "\n" if defined? $state
puts "----------------"
puts "final hash value: (H#{$blocks.size})"
puts "----------------"
8.times do |i|
puts "#{registers[i]} = #{bits($hash[i])} = #{hex($hash[i])}"
end
delay(:slowest)
# Frame - Concatenate
$digest = ""
8.times do |i|
$digest << hex($hash[i])
system "clear"
puts $state + "\n" if defined? $state
puts "----------------"
puts "final hash value: (H#{$blocks.size})"
puts "----------------"
8.times do |j|
puts "#{registers[j]} = #{bits($hash[j])} = #{hex($hash[j])}"
end
puts
puts "#{$digest}"
delay(:fastest)
end
delay(:end)
delay(:end) # extra delay for the absolute final frame

# =======
# SHA-256
# =======
# -----
# Utils - Handy functions for converting integers and strings to binary
# -----
# Convert integer to binary string (32 bits)
def bits(x, n = 32)
if x >= 0
return "%0#{n}b" % x
else
# Note: Ruby NOT function returns a negative number, and .to_s(2) displays this mathematical representation in base 2.
# Note: So to get the expected unsigned notation you need to get the individual bits instead.
# Note: When doing so, ignore the first bit because that's the sign bit.
# https://www.calleerlandsson.com/rubys-bitwise-operators/
return (n - 1).downto(0).map { |i| x[i] }.join
end
end
# Convert integer to hexadecimal string (32 bits)
def hex(i)
return i.to_s(16).rjust(8, "0")
end
# Convert string to binary string
def bitstring(string)
bytes = string.bytes # convert ascii characters to bytes (integers)
binary = bytes.map { |x| bits(x, 8) } # convert bytes to binary strings (8 bits in a byte)
return binary.join
end
# Use standard delay times between frames
def delay(speed)
if $delay == "enter"
STDIN.gets # gets on its own will try and read the contents of files passed in through ARGV (then use STDIN if not)
elsif $delay == "nodelay"
sleep 0
else
# Set speed
multiplier = 1
case $delay
when "fast"
multiplier = 0.5
end
case speed
when :fastest
sleep 0.1 * multiplier
when :fast
sleep 0.2 * multiplier
when :normal
sleep 0.4 * multiplier
when :slow
sleep 0.6 * multiplier
when :slowest
sleep 0.8 * multiplier
when :end
sleep 1.0 * multiplier
else
sleep speed
end
end
end
# Detect input type base on prefix (i.e. binary, hex, or otherwise just a string)
def input_type(input)
# Check for hex or binary prefix
case input[0..1]
when "0b"
# check it's a valid binary string
if input[2..-1] =~ /[^0-1]/ # only 1s and 0s
puts "Invalid binary string: #{input}"
exit
end
return "binary"
when "0x"
# check it's a valid hex string
if input[2..-1] !~ /^[0-9A-F]+$/i # only hex chars (case-insensitive)
puts "Invalid hex string: #{input}"
exit
end
return "hex"
else
return "string"
end
end
# Convert input (hex, ascii) to array of bytes
def bytes(input, type)
case type
when "binary"
bin = input[2..-1] # trim 0b prefix
if (bin.size % 8 == 0) # if we have been given a bitstring that makes up an exact number of bytes (8 bits in a byte)
bytes = bin.scan(/.{8}/).map {|byte| byte.to_i(2)} # convert the bits to array of bytes (in decimal)
else
bytes = "(bitstring is not an exact amount of bytes)" # helpful note
end
when "hex"
hex = input[2..-1] # trim 0x prefix
bytes = [hex].pack("H*").unpack("C*") # convert hex string to bytes
else
bytes = input.bytes # convert ASCII string to bytes
end
return bytes
end
# ----------
# Operations
# ----------
# Addition modulo 2**32
def add(*x)
total = x.inject(:+)
return total % 2 ** 32 # limits result of addition to 32 bits
end
# Rotate right (circular right shift)
def rotr(n, x)
right = (x >> n) # right shift
left = (x << 32 - n) # left shift
result = right | left # combine to create rotation effect
return result & (2 ** 32 - 1) # use mask to truncate result to 32 bits
end
# Shift right
def shr(n, x)
result = x >> n
return result
end
# ---------
# Functions - Combined rotations and shifts using operations above
# ---------
# σ0
def sigma0(x)
return rotr(7, x) ^ rotr(18, x) ^ shr(3, x)
end
# σ1
def sigma1(x)
return rotr(17, x) ^ rotr(19, x) ^ shr(10, x)
end
# Σ0 (uppercase)
def usigma0(x)
return rotr(2, x) ^ rotr(13, x) ^ rotr(22, x)
end
# Σ1
def usigma1(x)
return rotr(6, x) ^ rotr(11, x) ^ rotr(25, x)
end
# Choice - Use first bit to choose the (1)second or (0)third bit
def ch(x, y, z)
return (x & y) ^ (~x & z)
end
# Majority - Result is the majority of the three bits
def maj(x, y, z)
return (x & y) ^ (x & z) ^ (y & z)
end
# -------------
# Preprocessing
# -------------
# Pad binary string message to multiple of 512 bits
def padding(message)
l = message.size # size of message (in bits)
k = (448 - l - 1) % 512 # pad with zeros up to 448 bits (64 bits short of 512 bits)
l64 = bits(l, 64) # binary representation of message size (64 bits in length)
return message + "1" + ("0" * k) + l64 # don't forget "1" bit between message and padding
end
# Cut padded message in to 512-bit message blocks
def split(message, size = 512)
return message.scan(/.{#{size}}/)
end
# ----------------
# Message Schedule
# ----------------
# Calculate the 64 words for the message schedule from the message block
def calculate_schedule(block)
# The message block provides the first 16 words for the message schedule (512 bits / 32 bits = 16 words)
schedule = block.scan(/.{32}/).map { |w| w.to_i(2) } # convert from binary string to integer for calculations
# Calculate remaining 48 words
16.upto(63) do |i|
schedule << add(sigma1(schedule[i - 2]), schedule[i - 7], sigma0(schedule[i - 15]), schedule[i - 16])
end
return schedule
end
# ---------
# Constants
# ---------
# Constants = Cube roots of the first 64 prime numbers (first 32 bits of the fractional part)
K = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311].map { |prime| prime ** (1 / 3.0) }.map { |i| (i - i.floor) }.map { |i| (i * 2 ** 32).floor }
# -----------
# Compression - Run compression function on the message schedule and constants
# -----------
# Initial Hash Values = Square roots of the first 8 prime numbers (first 32 bits of the fractional part)
IV = [2, 3, 5, 7, 11, 13, 17, 19].map { |prime| prime ** (1 / 2.0) }.map { |i| (i - i.floor) }.map { |i| (i * 2 ** 32).floor }
def compression(initial, schedule, constants)
# state register - set initial values ready for the compression function
h = initial[7]
g = initial[6]
f = initial[5]
e = initial[4]
d = initial[3]
c = initial[2]
b = initial[1]
a = initial[0]
# compression function - update state for every word in the message schedule
64.times do |i|
# calculate temporary words
t1 = add(schedule[i], constants[i], usigma1(e), ch(e, f, g), h)
t2 = add(usigma0(a), maj(a, b, c))
# rotate state registers one position and add in temporary words
h = g
g = f
f = e
e = add(d, t1)
d = c
c = b
b = a
a = add(t1, t2)
end
# Final hash values are previous intermediate hash values added to output of compression function
hash = []
hash[7] = add(initial[7], h)
hash[6] = add(initial[6], g)
hash[5] = add(initial[5], f)
hash[4] = add(initial[4], e)
hash[3] = add(initial[3], d)
hash[2] = add(initial[2], c)
hash[1] = add(initial[1], b)
hash[0] = add(initial[0], a)
#hash = initial.zip(updated).map {|i, u| add(i, u)} # succinct method for adding one array on top of another (but not as readable)
# return final state
return hash
end
# -------
# SHA-256 - Complete SHA-256 function
# -------
def sha256(string)
# 0. Convert String to Binary
# ---------------------------
message = bitstring(string)
# 1. Preprocessing
# ----------------
# Pad message
padded = padding(message)
# Split up in to 512 bit message blocks
blocks = split(padded, 512)
# 2. Hash Computation
# -------------------
# Set initial hash state using initial hash values
hash = IV
# For each message block
blocks.each do |block|
# Prepare 64 word message schedule
schedule = calculate_schedule(block)
# Remember starting hash values
initial = hash.clone
# Apply compression function to update hash values
hash = compression(initial, schedule, constants = K)
end
# 3. Result
# ---------
# Convert hash values to hexadecimal and concatenate
return hash.map { |w| "%08x" % w }.join
end
# --------
# Examples
# --------
#require 'digest' # for testing
#puts sha256("") == Digest::SHA256.hexdigest("") #=> e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
#puts sha256("abc") == Digest::SHA256.hexdigest("abc") #=> ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
#puts sha256("learnmeabitcoin") == Digest::SHA256.hexdigest("learnmeabitcoin") #=> ef235aacf90d9f4aadd8c92e4b2562e1d9eb97f0df9ba3b58258739cb013db2
#puts sha256("xyz"*1000) == Digest::SHA256.hexdigest("xyz"*1000)

require_relative "sha256lib.rb"
# -------------------
# Initial Hash Values - H0
# -------------------
# The first thirty-two bits of the fractional parts of the square roots of the first eight prime numbers.
#
# Why?
# * These initial values don't _need_ to be anything in particular.
# * These are random-looking, irrational, and relatively independent from each other.
# * Using publicly-available numbers means that the initial hash values are less likely to have been chosen to allow for a backdoor.
# H0 = 6a09e667
# H1 = bb67ae85
# H2 = 3c6ef372
# H3 = a54ff53a
# H4 = 510e527f
# H5 = 9b05688c
# H6 = 1f83d9ab
# H7 = 5be0cd19
primes = [2, 3, 5, 7, 11, 13, 17, 19]
# --------
# Settings
# --------
indent = " " * 2
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression:"
puts "#{indent}-----------"
registers = ("a".."h").to_a
8.times do |i|
puts "#{indent}#{registers[i]} ="
end
delay(:slow)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H0)"
puts "#{indent}-----------"
8.times do |i|
puts "#{indent}#{registers[i]} ="
end
delay(:slow)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H0) (initial hash value)"
puts "#{indent}-----------"
8.times do |i|
puts "#{indent}#{registers[i]} ="
end
delay(:slowest)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H0) (initial hash value)"
puts "#{indent}-----------"
8.times do |i|
puts "#{indent}#{registers[i]} = √#{primes[i]}"
end
delay(:slowest)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H0) (initial hash value)"
puts "#{indent}-----------"
8.times do |i|
puts "#{indent}#{registers[i]} = #{Math.sqrt(primes[i]).round(10)}"
end
delay(:slow)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H0) (initial hash value)"
puts "#{indent}-----------"
8.times do |i|
puts "#{indent}#{registers[i]} = #{(Math.sqrt(primes[i]) - Math.sqrt(primes[i]).floor).round(10)}"
end
delay(:slow)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H0) (initial hash value)"
puts "#{indent}-----------"
8.times do |i|
puts "#{indent}#{registers[i]} = #{(Math.sqrt(primes[i]) - Math.sqrt(primes[i]).floor).round(10)} * 2^32"
end
delay(:slow)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H0) (initial hash value)"
puts "#{indent}-----------"
8.times do |i|
puts "#{indent}#{registers[i]} = #{((Math.sqrt(primes[i]) - Math.sqrt(primes[i]).floor) * 2 ** 32).floor}"
end
delay(:slow)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H0) (initial hash value)"
puts "#{indent}-----------"
8.times do |i|
puts "#{indent}#{registers[i]} = #{bits(((Math.sqrt(primes[i]) - Math.sqrt(primes[i]).floor) * 2 ** 32).floor)}"
end
delay(:slow)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (H0)"
puts "#{indent}-----------"
8.times do |i|
puts "#{indent}#{registers[i]} = #{bits(((Math.sqrt(primes[i]) - Math.sqrt(primes[i]).floor) * 2 ** 32).floor)}"
end
delay(:end)

# coding: utf-8
require_relative "sha256lib.rb"
# --------
# Majority
# --------
# Maj(x, y, z) = (x & y) ^ (x & z) ^ (y & z)
#
# Use the majority of x, y, z to set the result bit.
# -----
# Input
# -----
# defaults
x = 0b00000000111111110000000011111111 # 0x428a2f98
y = 0b00000000000000001111111111111111 # 0x71374491
z = 0b11111111111111110000000000000000 # 0xb5c0fbcf
# arguments passed
if ARGV.size == 3
x = ARGV[0].to_i(2)
y = ARGV[1].to_i(2)
z = ARGV[2].to_i(2)
end
# ---------
# Animation
# ---------
32.downto(1) do |i|
system "clear"
maj = bits( (x & y) ^ (x & z) ^ (y & z) )
puts "▼".rjust(i+3, " ")
puts "x: #{bits(x)} #{bits(x)[i-1]}"
puts "y: #{bits(y)} #{bits(y)[i-1]}"
puts "z: #{bits(z)} #{bits(z)[i-1]}"
puts " #{'-'*32}"
puts maj[i-1..-1].rjust(35, " ")
sleep(0.1)
end
sleep 1

require_relative 'sha256lib.rb'
# -------
# Default
# -------
if !defined? $input
# default
$input = "abc"
$type = "string"
# argument passed
$input = ARGV[0] if ARGV[0] # only accept strings for now
# calculate message
$bytes = $input.bytes
$message = $input.bytes.map {|x| x.to_s(2).rjust(8, "0")}.join
end
# puts string.bytes.inspect # [97, 98, 99]
# puts string.bytes.map{|x| x.to_s(16)}.inspect # ["61", "62", "63"]
# puts string.bytes.map{|x| x.to_s(2)}.inspect # ["1100001", "1100010", "1100011"]
# puts string.unpack("B*") # 011000010110001001100011
# ---------
# Animation
# ---------
system "clear"
puts "-------"
puts "message:"
puts "-------"
delay(:fast)
system "clear"
puts "-------"
puts "message:"
puts "-------"
puts "input: #{$input} (#{$type})"
delay(:normal)
system "clear"
puts "-------"
puts "message:"
puts "-------"
puts "input: #{$input} (#{$type})"
puts "bytes: #{$bytes.inspect}" if defined? $bytes
delay(:normal)
system "clear"
puts "-------"
puts "message:"
puts "-------"
puts "input: #{$input} (#{$type})"
puts "bytes: #{$bytes.inspect}" if defined? $bytes
puts "message: #{$message}"
delay(:end)
# Save Final State
$state = <<-FRAME
-------
message:
-------
input: #{$input} (#{$type})
bytes: #{$bytes.inspect}
message: #{$message}
FRAME

require_relative "sha256lib.rb"
# -------
# Default
# -------
if !defined? $input
# default
$input = "abc"
$message = $input.unpack("B*")[0] # 011000010110001001100011
# argument passed
$message = ARGV[0] if ARGV[0] # accept binary message string
end
# -------
# Padding
# -------
# pad the message so that it's a multiple of 512 bits
$l = $message.size # length of message
$k = (448 - $l - 1) % 512 # pad with zeros up to 448 bits (64 short of 512 bits)
# message padding size M
# -------------------------------------------------------------
# | M |1|...00000000000000000000|...0000001100|
# -------------------------------------------------------------
# <----------------- 448 bits ----------------> <- 64 bits ->
$padded = $message + "1" + ("0" * $k) + $l.to_s(2).rjust(64, "0")
# ---------
# Animation
# ---------
system "clear"
puts $state + "\n" if defined? $state
puts "-------"
puts "padding:"
puts "-------"
delay(:normal)
system "clear"
puts $state + "\n" if defined? $state
puts "-------"
puts "padding: (#{$message.size} bits)"
puts "-------"
puts "message: #{$message}"
delay(:normal)
system "clear"
puts $state + "\n" if defined? $state
puts "-------"
puts "padding: (#{($message + "1").size} bits)"
puts "-------"
puts "message: #{$message}1"
delay(:normal)
system "clear"
puts $state + "\n" if defined? $state
puts "-------"
puts "padding: (#{($message + "1").size} bits -> #{($message + "1").size + $k} bits)"
puts "-------"
print "message: #{$message}1"
if $delay == "enter" || $delay == "nodelay" # show all padded zeros in one go if we're stepping through with keyboard
puts "0" * $k
else
$k.times do |i|
print "0"
sleep 0.005
end
end
delay(:normal)
system "clear"
puts $state + "\n" if defined? $state
puts "-------"
puts "padding: (#{($message + "1").size + $k} bits)"
puts "-------"
print "message: #{$message}1#{"0" * $k}"
delay(:normal)
system "clear"
puts $state + "\n" if defined? $state
puts "-------"
puts "padding: (#{$padded.size} bits)"
puts "-------"
puts "message: #{$padded}"
delay(:end)
# Save Final State
$state = <<-FRAME
#{$state}
-------
padding: (#{$padded.size} bits)
-------
message: #{$padded}
FRAME

# -----------
# Shift Right
# -----------
def rotr(n, x)
mask = 2**32 - 1
right = (x >> n) & mask
left = (x << 32-n) & mask
result = right | left
return result
end
# -----
# Input
# -----
# defaults
x = 0b11111111000000001111111100000000 #0b11101001101101011101101110100101
n = 32
# arguments passed
x = ARGV[0].to_i(2) if ARGV[0] # binary
n = ARGV[1].to_i if ARGV[1] # integer
# check arguments
if ARGV[0] && ARGV[0].size > 32
puts "We only operate on 32-bit words in SHA-256. Your x is #{ARGV[0].size} bits."; exit
end
# ---------
# Animation
# ---------
s = n.to_s.ljust(2, " ")
n.times do |i|
system "clear"
i += 1
puts " x: #{"%032b" % x}"
puts "ROTR #{s}: #{"%032b" % rotr(i, x)}"
sleep 0.10
end
sleep 0.5

# coding: utf-8
require_relative "sha256lib.rb"
# -------
# Default
# -------
if !defined? $input
# default
$input = "abc"
$message = $input.unpack("B*")[0] # 011000010110001001100011
$padded = padding($message)
$blocks = split($padded, 512)
$block_number = 0 # message block number
$block = $blocks[$block_number]
# argument passed
$block = ARGV[0] if ARGV[0] # accept 512 bit binary string as message block
end
# Set variables (these are global variables given to us by the parent sha256.rb script)
if defined? $block
$block = $block
$block_number = $block_number
end
# ----------------
# Message Schedule
# ----------------
# Get size of block
size = $block.size
# The message block provides the first 16 words for the message schedule (512 bits / 32 bits = 16 words)
$schedule = $block.scan(/.{32}/).map { |w| w.to_i(2) } # convert from binary string to integer for calculations
# Remember the values used to calculate each word from 16 to 63
memory = Array.new(16) # leave first 16 blank because they were not calculated from previous values
# Calculate remaining 48 words
16.upto(63) do |i|
$schedule << add(sigma1($schedule[i - 2]), $schedule[i - 7], sigma0($schedule[i - 15]), $schedule[i - 16])
memory << [sigma1($schedule[i - 2]), $schedule[i - 7], sigma0($schedule[i - 15]), $schedule[i - 16]] # store the values used in the calculation as we go
end
# --------
# Settings
# --------
indent = " " * 2
# ---------
# Animation
# ---------
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-------"
puts "#{indent}block #{$block_number}:"
puts "#{indent}-------"
puts "#{indent}#{$block}"
delay(:slowest)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-------"
puts "#{indent}block #{$block_number}:"
puts "#{indent}-------"
puts "#{indent}#{$block}"
puts
puts "#{indent}----------------"
puts "#{indent}message schedule:"
puts "#{indent}----------------"
delay(:slowest)
# Frame
64.times do |i|
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-------"
puts "#{indent}block #{$block_number}:"
puts "#{indent}-------"
if i <= 15
puts "#{indent}#{$block[((i + 1) * 32)..-1].ljust(size, " ")}"
else
puts "#{indent}#{" " * size}" # leave space where it used to be
end
puts
puts "#{indent}----------------"
puts "#{indent}message schedule:"
puts "#{indent}----------------"
(i + 1).times do |j|
# first 16 value are just words from the message block
if i <= 15
puts "#{indent}W#{j.to_s.ljust(2, " ")} #{bits($schedule[j])}"
end
# show values used in calculation for last 48 words
if i >= 16
if j < i - 16
# show nothing
elsif j == i - 16
puts "#{indent}W#{j.to_s.ljust(2, " ")} #{bits($schedule[j])} -> #{bits(memory[i][3])}"
elsif j == i - 15
puts "#{indent}W#{j.to_s.ljust(2, " ")} #{bits($schedule[j])} -> σ0 #{bits(memory[i][2])}"
elsif j == i - 7
puts "#{indent}W#{j.to_s.ljust(2, " ")} #{bits($schedule[j])} -> #{bits(memory[i][1])}"
elsif j == i - 2
puts "#{indent}W#{j.to_s.ljust(2, " ")} #{bits($schedule[j])} -> σ1 #{bits(memory[i][0])}"
elsif j == i
puts "#{indent}W#{j.to_s.ljust(2, " ")} #{bits($schedule[j])} = σ1(t-2) + (t-7) + σ0(t-15) + (t-16)"
else
puts "#{indent}W#{j.to_s.ljust(2, " ")} #{bits($schedule[j])}"
end
end
end
# pause before calculating remaining 48 words after the initial 16
if i == 15
delay(:normal)
else
delay(:fastest)
end
end
delay(:normal)
# Frame
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-------"
puts "#{indent}block #{$block_number}:"
puts "#{indent}-------"
puts "#{indent}#{" " * size}"
puts
puts "#{indent}----------------"
puts "#{indent}message schedule:"
puts "#{indent}----------------"
47.upto(63) do |i|
puts "#{indent}W#{i.to_s.ljust(2, " ")} #{bits($schedule[i])}"
end
delay(:end)
# Save Final State
$state = <<-FRAME
#{$state}
#{indent}-------
#{indent}block #{$block_number}:
#{indent}-------
#{indent}#{" " * size}
#{indent}----------------
#{indent}message schedule:
#{indent}----------------
#{indent}W#{47.to_s.ljust(2, " ")} #{bits($schedule[47])}
#{indent}W#{48.to_s.ljust(2, " ")} #{bits($schedule[48])}
#{indent}W#{49.to_s.ljust(2, " ")} #{bits($schedule[49])}
#{indent}W#{50.to_s.ljust(2, " ")} #{bits($schedule[50])}
#{indent}W#{51.to_s.ljust(2, " ")} #{bits($schedule[51])}
#{indent}W#{52.to_s.ljust(2, " ")} #{bits($schedule[52])}
#{indent}W#{53.to_s.ljust(2, " ")} #{bits($schedule[53])}
#{indent}W#{54.to_s.ljust(2, " ")} #{bits($schedule[54])}
#{indent}W#{55.to_s.ljust(2, " ")} #{bits($schedule[55])}
#{indent}W#{56.to_s.ljust(2, " ")} #{bits($schedule[56])}
#{indent}W#{57.to_s.ljust(2, " ")} #{bits($schedule[57])}
#{indent}W#{58.to_s.ljust(2, " ")} #{bits($schedule[58])}
#{indent}W#{59.to_s.ljust(2, " ")} #{bits($schedule[59])}
#{indent}W#{60.to_s.ljust(2, " ")} #{bits($schedule[60])}
#{indent}W#{61.to_s.ljust(2, " ")} #{bits($schedule[61])}
#{indent}W#{62.to_s.ljust(2, " ")} #{bits($schedule[62])}
#{indent}W#{63.to_s.ljust(2, " ")} #{bits($schedule[63])}
FRAME
system "clear"
puts $state

require_relative "sha256lib.rb"
# -------
# Default
# -------
if !defined? $input
# Command Line Arguments
$input = ARGV[0] || "abc" # "string"|"0xaabbcc"|"0b10110100"
$delay = ARGV[1] || "normal" # [enter|normal|fast|nodelay]
# Detect input type (binary, hex, or string)
$type = input_type($input)
# Convert input to bytes (if possible)
$bytes = bytes($input, $type)
# Set message (binary representation of data)
if $type == "string" || $type == "hex"
$message = $bytes.map { |x| x.to_s(2).rjust(8, "0") }.join # convert bytes to binary string
end
if $type == "binary"
$message = $input[2..-1] # input is already in binary, so just trim the leading 0b from the input
end
# Note about hitting enter to step
if $delay == "enter"
puts "Hit enter to step through."
STDIN.gets
end
# Catch Ctrl-C to prevent unsightly errors when terminating early
Signal.trap("SIGINT") do
exit
end
end
# 1. Message
load "message.rb"
# 2. Padding
load "padding.rb"
# 3. Message Blocks
load "blocks.rb"
# For each block
$blocks.each.with_index do |block, i|
# make variables global so scripts can access them
$block = block
$block_number = i
# 4. Message Schedule
load "schedule.rb"
# 5. Compression (Initial Hash Values)
load "initial.rb" if $block_number == 0 # Only set initial hash values on first run
# 5. Compression
load "compression.rb" # Use hash values from previous compression otherwise
end
# 6. Final Hash
load "final.rb"

# -----------
# Shift Right
# -----------
def shr(n, x)
x >> n
end
# -----
# Input
# -----
# defaults
x = 0b11111111000000001111111100000000 #0b11101001101101011101101110100101
n = 32
# arguments passed
x = ARGV[0].to_i(2) if ARGV[0] # binary
n = ARGV[1].to_i if ARGV[1] # integer
# check arguments
if ARGV[0] && ARGV[0].size > 32
puts "We only operate on 32-bit words in SHA-256. Your x is #{ARGV[0].size} bits."; exit
end
# ---------
# Animation
# ---------
s = n.to_s.ljust(2, " ")
n.times do |i|
system "clear"
i += 1
puts " x: #{"%032b" % x}"
puts " SHR #{s}: #{"%032b" % shr(i, x)}"
sleep 0.1
end
sleep 0.4

# coding: utf-8
require_relative "sha256lib.rb"
# -----
# σ0(x)
# -----
# σ0(x) = ROTR(7, x) ^ ROTR(18, x) ^ SHR(3, x)
# -----
# Input
# -----
# default
x = 0b00000000000000000011111111111111 # 0b11101001101101011101101110100101
# argument passed
x = ARGV[0].to_i(2) if ARGV[0] # binary
# check arguments
if ARGV[0] && ARGV[0].size > 32
puts "We only operate on 32-bit words in SHA-256. Your x is #{ARGV[0].size} bits."; exit
end
# ---------
# Animation
# ---------
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 7: #{bits(x)}"
puts "ROTR 18: #{bits(x)}"
puts " SHR 3: #{bits(x)}"
puts " #{'-'*32}"
puts "σ0(x):"
sleep(0.1)
# ROTR(7, x)
(7+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 7: #{bits(rotr(i, x))}"
puts "ROTR 18: #{bits(x)}"
puts " SHR 3: #{bits(x)}"
puts " #{'-'*32}"
puts "σ0(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(18, x)
(18+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 7: #{bits(rotr(7, x))}"
puts "ROTR 18: #{bits(rotr(i, x))}"
puts " SHR 3: #{bits(x)}"
puts " #{'-'*32}"
puts "σ0(x):"
sleep(0.1)
end
sleep(0.1)
# SHR(3, x)
(3+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 7: #{bits(rotr(7, x))}"
puts "ROTR 18: #{bits(rotr(18, x))}"
puts " SHR 3: #{bits(shr(i, x))}"
puts " #{'-'*32}"
puts "σ0(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(7, x) ^ ROTR(18, x) ^ SHR(3, x)
32.downto(1) do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 7: #{bits(rotr(7, x))}"
puts "ROTR 18: #{bits(rotr(18, x))} XOR"
puts " SHR 3: #{bits(shr(3, x))} XOR"
puts " #{'-'*32}"
puts "σ0(x): #{bits(rotr(7, x) ^ rotr(18, x) ^ shr(3, x))[i-1..-1].rjust(32, " ")}"
sleep(0.1)
end
sleep(1)

# coding: utf-8
require_relative "sha256lib.rb"
# -----
# σ1(x)
# -----
# σ1(x) = ROTR(17, x) ^ ROTR(19, x) ^ SHR(10, x)
# -----
# Input
# -----
# default
x = 0b00000000000000000011111111111111 # 0b11101001101101011101101110100101
# argument passed
x = ARGV[0].to_i(2) if ARGV[0] # binary
# check arguments
if ARGV[0] && ARGV[0].size > 32
puts "We only operate on 32-bit words in SHA-256. Your x is #{ARGV[0].size} bits."; exit
end
# ---------
# Animation
# ---------
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 17: #{bits(x)}"
puts "ROTR 19: #{bits(x)}"
puts " SHR 10: #{bits(x)}"
puts " #{'-'*32}"
puts "σ1(x):"
sleep(0.1)
# ROTR(17, x)
(17+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 17: #{bits(rotr(i, x))}"
puts "ROTR 19: #{bits(x)}"
puts " SHR 10: #{bits(x)}"
puts " #{'-'*32}"
puts "σ1(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(19, x)
(19+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 17: #{bits(rotr(17, x))}"
puts "ROTR 19: #{bits(rotr(i, x))}"
puts " SHR 10: #{bits(x)}"
puts " #{'-'*32}"
puts "σ1(x):"
sleep(0.1)
end
sleep(0.1)
# SHR(10, x)
(10+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 17: #{bits(rotr(17, x))}"
puts "ROTR 19: #{bits(rotr(19, x))}"
puts " SHR 10: #{bits(shr(i, x))}"
puts " #{'-'*32}"
puts "σ1(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(17, x) ^ ROTR(19, x) ^ SHR(10, x)
32.downto(1) do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 17: #{bits(rotr(17, x))}"
puts "ROTR 19: #{bits(rotr(19, x))} XOR"
puts " SHR 10: #{bits(shr(10, x))} XOR"
puts " #{'-'*32}"
puts "σ1(x): #{bits(rotr(17, x) ^ rotr(19, x) ^ shr(10, x))[i-1..-1].rjust(32, " ")}"
sleep(0.1)
end
sleep(1)

# coding: utf-8
require_relative "sha256lib.rb"
# -------
# Default
# -------
if !defined? $input
$input = "abc"
$message = $input.unpack("B*")[0] # 011000010110001001100011
$padded = padding($message)
$blocks = split($padded, 512)
# message block
$block_number = 0 # message block number
$block = $blocks[$block_number]
# message schedule
$schedule = calculate_schedule($block)
end
# Schedule (Wt)
w = $schedule
# Constants (Kt)
k = K
# Initial Hash Values
initial = IV
$hash = initial.clone
# --------
# Settings
# --------
indent = " " * 2
# ---------
# Animation
# ---------
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts
puts
puts
puts
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts
puts
puts
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 ="
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:slow)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:slow)
# Ch(e, f, g)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} ->"
puts "#{indent}f = #{bits($hash[5])} ->"
puts "#{indent}g = #{bits($hash[6])} ->"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Ch(e, f, g)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])} -> #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} -> #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Ch(e, f, g)
32.downto(1) do |i|
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{"▼".rjust(i, " ")}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])} -> #{bits($hash[5])} #{bits($hash[4])[i-1] == '1' ? '◄' : ' '}"
puts "#{indent}g = #{bits($hash[6])} -> #{bits($hash[6])} #{bits($hash[4])[i-1] == '0' ? '◄' : ' '}"
puts "#{indent}h = #{bits($hash[7])} #{bits(ch($hash[4], $hash[5], $hash[6]))[i-1..-1].rjust(32, " ")} Ch(e, f, g)"
delay(:fastest)
end
delay(:normal)
# Ch(e, f, g)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])} -> #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} -> #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
delay(:normal)
# Ch(e, f, g)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
delay(:normal)
# Ch(e, f, g)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ1(e)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} -> "
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fast)
# Σ1(e)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fast)
# Σ1(e)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits($hash[4])}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fast)
# Σ1(e)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])} #{bits($hash[4])}"
puts "#{indent}d = #{bits($hash[3])} #{bits($hash[4])}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ1(e)
6.times do |i|
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])} #{bits(rotr(i+1, $hash[4]))} ROTR 6"
puts "#{indent}d = #{bits($hash[3])} #{bits($hash[4])}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
end
delay(:normal)
# Σ1(e)
11.times do |i|
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])} #{bits(rotr(6, $hash[4]))} ROTR 6"
puts "#{indent}d = #{bits($hash[3])} #{bits(rotr(i+1, $hash[4]))} ROTR 11"
puts "#{indent}e = #{bits($hash[4])} -> #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
end
delay(:normal)
# Σ1(e)
25.times do |i|
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])} #{bits(rotr(6, $hash[4]))} ROTR 6"
puts "#{indent}d = #{bits($hash[3])} #{bits(rotr(11, $hash[4]))} ROTR 11"
puts "#{indent}e = #{bits($hash[4])} -> #{bits(rotr(i+1, $hash[4]))} ROTR 25"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
end
delay(:normal)
# Σ1(e)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])} #{bits(rotr(6, $hash[4]))}"
puts "#{indent}d = #{bits($hash[3])} #{bits(rotr(11, $hash[4]))}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits(rotr(25, $hash[4]))}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ1(e)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])} #{bits(rotr(6, $hash[4]))} XOR"
puts "#{indent}d = #{bits($hash[3])} #{bits(rotr(11, $hash[4]))}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits(rotr(25, $hash[4]))}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ1(e)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(rotr(11, $hash[4]) ^ rotr(6, $hash[4]))} XOR"
puts "#{indent}e = #{bits($hash[4])} -> #{bits(rotr(25, $hash[4]))}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ1(e)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} -> #{bits(rotr(11, $hash[4]) ^ rotr(6, $hash[4]) ^ rotr(25, $hash[4]))} Σ1(e)"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ1(e)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} #{bits(usigma1($hash[4]))} Σ1(e)"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# h
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} #{bits(usigma1($hash[4]))} Σ1(e)"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])} -> "
delay(:normal)
# h
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} #{bits(usigma1($hash[4]))} Σ1(e)"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])} -> #{bits($hash[7])}"
delay(:normal)
# h
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} #{bits(usigma1($hash[4]))} Σ1(e)"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])} -> #{bits($hash[7])} h"
delay(:normal)
# h
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} #{bits(usigma1($hash[4]))} Σ1(e)"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])} #{bits($hash[7])} h"
delay(:normal)
# T1
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = "
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} #{bits(usigma1($hash[4]))} Σ1(e)"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])} #{bits($hash[7])} h"
delay(:normal)
# T1
system "clear"
t1 = add(w[0], k[0], usigma1($hash[4]), ch($hash[4], $hash[5], $hash[6]), $hash[7])
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T1)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0 = #{bits(t1)}"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])} #{bits(usigma1($hash[4]))} Σ1(e)"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])} #{bits(ch($hash[4], $hash[5], $hash[6]))} Ch(e, f, g)"
puts "#{indent}h = #{bits($hash[7])} #{bits($hash[7])} h"
delay(:end)

# coding: utf-8
require_relative "sha256lib.rb"
# -------
# Default
# -------
if !defined? $input
$input = "abc"
$message = $input.unpack("B*")[0] # 011000010110001001100011
$padded = padding($message)
$blocks = split($padded, 512)
# message block
$block_number = 0 # message block number
$block = $blocks[$block_number]
# message schedule
$schedule = calculate_schedule($block)
end
# Schedule (Wt)
w = $schedule
# Constants (Kt)
k = K
# Initial Hash Values
initial = IV
$hash = initial.clone
# T1
t1 = add(w[0], k[0], usigma1($hash[4]), ch($hash[4], $hash[5], $hash[6]), $hash[7])
# --------
# Settings
# --------
indent = " " * 2
# ---------
# Animation
# ---------
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 ="
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Start
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Maj(a, b, c)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> "
puts "#{indent}b = #{bits($hash[1])} -> "
puts "#{indent}c = #{bits($hash[2])} -> "
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Maj(a, b, c)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])} -> #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])} -> #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])}"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Maj(a, b, c)
32.downto(1) do |i|
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts "#{indent} #{ " " * 32 } #{"▼".rjust(i, " ")}"
puts "#{indent}a = #{bits($hash[0])} -> #{bits($hash[0])} #{bits(initial[0])[i-1]}"
puts "#{indent}b = #{bits($hash[1])} -> #{bits($hash[1])} #{bits(initial[1])[i-1]}"
puts "#{indent}c = #{bits($hash[2])} -> #{bits($hash[2])} #{bits(initial[2])[i-1]}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))[i-1..-1].rjust(32, " ")} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
end
delay(:normal)
# Maj(a, b, c)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])} -> #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])} -> #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Maj(a, b, c)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} ->"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fast)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fast)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])} #{bits($hash[0])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fast)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits($hash[0])}"
puts "#{indent}b = #{bits($hash[1])} #{bits($hash[0])}"
puts "#{indent}c = #{bits($hash[2])} #{bits($hash[0])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ0(a)
2.times do |i|
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits(rotr(i+1, $hash[0]))} ROTR 2"
puts "#{indent}b = #{bits($hash[1])} #{bits($hash[0])}"
puts "#{indent}c = #{bits($hash[2])} #{bits($hash[0])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
end
delay(:normal)
# Σ0(a)
13.times do |i|
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits(rotr(2, $hash[0]))} ROTR 2"
puts "#{indent}b = #{bits($hash[1])} #{bits(rotr(i+1, $hash[0]))} ROTR 13"
puts "#{indent}c = #{bits($hash[2])} #{bits($hash[0])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
end
delay(:normal)
# Σ0(a)
22.times do |i|
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits(rotr(2, $hash[0]))} ROTR 2"
puts "#{indent}b = #{bits($hash[1])} #{bits(rotr(13, $hash[0]))} ROTR 13"
puts "#{indent}c = #{bits($hash[2])} #{bits(rotr(i+1, $hash[0]))} ROTR 22"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:fastest)
end
delay(:normal)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits(rotr(2, $hash[0]))}"
puts "#{indent}b = #{bits($hash[1])} #{bits(rotr(13, $hash[0]))}"
puts "#{indent}c = #{bits($hash[2])} #{bits(rotr(22, $hash[0]))}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits(rotr(2, $hash[0]))}"
puts "#{indent}b = #{bits($hash[1])} #{bits(rotr(13, $hash[0]))}"
puts "#{indent}c = #{bits($hash[2])} #{bits(rotr(22, $hash[0]))} XOR"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits(rotr(2, $hash[0]))}"
puts "#{indent}b = #{bits($hash[1])} #{bits(rotr(13, $hash[0]) ^ rotr(22, $hash[0]))} XOR"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} -> #{bits(rotr(2, $hash[0]) ^ rotr(13, $hash[0]) ^ rotr(22, $hash[0]))} Σ0(a)"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c)"
puts
puts "#{indent}a = #{bits($hash[0])} #{bits(usigma0($hash[0]))} Σ0(a)"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ0(a)
system "clear"
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = "
puts
puts "#{indent}a = #{bits($hash[0])} #{bits(usigma0($hash[0]))} Σ0(a)"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:normal)
# Σ0(a)
system "clear"
t2 = add(usigma0($hash[0]), maj($hash[0], $hash[1], $hash[2]))
puts $state + "\n" if defined? $state
puts "#{indent}-----------"
puts "#{indent}compression: (T2)"
puts "#{indent}-----------"
puts "#{indent}W0 = #{bits(w[0])} (message schedule)"
puts "#{indent}K0 = #{bits(k[0])} (constant)"
puts
puts "#{indent}T1 = Σ1(e) + Ch(e, f, g) + h + K0 + W0"
puts "#{indent}T2 = Σ0(a) + Maj(a, b, c) = #{bits(t2)}"
puts
puts "#{indent}a = #{bits($hash[0])} #{bits(usigma0($hash[0]))} Σ0(a)"
puts "#{indent}b = #{bits($hash[1])}"
puts "#{indent}c = #{bits($hash[2])}"
puts "#{indent}d = #{bits($hash[3])} #{bits(maj($hash[0], $hash[1], $hash[2]))} Maj(a, b, c)"
puts "#{indent}e = #{bits($hash[4])}"
puts "#{indent}f = #{bits($hash[5])}"
puts "#{indent}g = #{bits($hash[6])}"
puts "#{indent}h = #{bits($hash[7])}"
delay(:end)

# coding: utf-8
require_relative "sha256lib.rb"
# -----
# Σ0(x)
# -----
# Σ0(x) = ROTR(2, x) ^ ROTR(13, x) ^ ROTR(22, x)
# -----
# Input
# -----
# default
x = 0b00000000000000000011111111111111 # 0b11101001101101011101101110100101
# argument passed
x = ARGV[0].to_i(2) if ARGV[0] # binary
# check arguments
if ARGV[0] && ARGV[0].size > 32
puts "We only operate on 32-bit words in SHA-256. Your x is #{ARGV[0].size} bits."; exit
end
# ---------
# Animation
# ---------
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 2: #{bits(x)}"
puts "ROTR 13: #{bits(x)}"
puts "ROTR 22: #{bits(x)}"
puts " #{'-'*32}"
puts "Σ0(x):"
sleep(0.1)
# ROTR(2, x)
(2+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 2: #{bits(rotr(i, x))}"
puts "ROTR 13: #{bits(x)}"
puts "ROTR 22: #{bits(x)}"
puts " #{'-'*32}"
puts "Σ0(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(13, x)
(13+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 2: #{bits(rotr(2, x))}"
puts "ROTR 13: #{bits(rotr(i, x))}"
puts "ROTR 22: #{bits(x)}"
puts " #{'-'*32}"
puts "Σ0(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(22, x)
(22+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 2: #{bits(rotr(2, x))}"
puts "ROTR 13: #{bits(rotr(13, x))}"
puts "ROTR 22: #{bits(rotr(i, x))}"
puts " #{'-'*32}"
puts "Σ0(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(2, x) ^ ROTR(13, x) ^ ROTR(22, x)
32.downto(1) do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 2: #{bits(rotr(2, x))}"
puts "ROTR 13: #{bits(rotr(13, x))} XOR"
puts "ROTR 22: #{bits(rotr(22, x))} XOR"
puts " #{'-'*32}"
puts "Σ0(x): #{bits(rotr(2, x) ^ rotr(13, x) ^ rotr(22, x))[i-1..-1].rjust(32, " ")}"
sleep(0.1)
end
sleep(1)

# coding: utf-8
require_relative "sha256lib.rb"
# -----
# Σ1(x)
# -----
# Σ1(x) = ROTR(6, x) ^ ROTR(11, x) ^ ROTR(25, x)
# -----
# Input
# -----
# default
x = 0b00000000000000000011111111111111 # 0b01010001000011100101001001111111
# argument passed
x = ARGV[0].to_i(2) if ARGV[0] # binary
# check arguments
if ARGV[0] && ARGV[0].size > 32
puts "We only operate on 32-bit words in SHA-256. Your x is #{ARGV[0].size} bits."; exit
end
# ---------
# Animation
# ---------
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 6: #{bits(x)}"
puts "ROTR 11: #{bits(x)}"
puts "ROTR 25: #{bits(x)}"
puts " #{'-'*32}"
puts "Σ1(x):"
sleep(0.1)
# ROTR(6, x)
(6+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 6: #{bits(rotr(i, x))}"
puts "ROTR 11: #{bits(x)}"
puts "ROTR 25: #{bits(x)}"
puts " #{'-'*32}"
puts "Σ1(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(11, x)
(11+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 6: #{bits(rotr(6, x))}"
puts "ROTR 11: #{bits(rotr(i, x))}"
puts "ROTR 25: #{bits(x)}"
puts " #{'-'*32}"
puts "Σ1(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(25, x)
(25+1).times do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 6: #{bits(rotr(6, x))}"
puts "ROTR 11: #{bits(rotr(11, x))}"
puts "ROTR 25: #{bits(rotr(i, x))}"
puts " #{'-'*32}"
puts "Σ1(x):"
sleep(0.1)
end
sleep(0.1)
# ROTR(6, x) ^ ROTR(11, x) ^ ROTR(25, x)
32.downto(1) do |i|
system "clear"
puts "x: #{bits(x)}"
puts " #{'-'*32}"
puts "ROTR 6: #{bits(rotr(6, x))}"
puts "ROTR 11: #{bits(rotr(11, x))} XOR"
puts "ROTR 25: #{bits(rotr(25, x))} XOR"
puts " #{'-'*32}"
puts "Σ1(x): #{bits(rotr(6, x) ^ rotr(11, x) ^ rotr(25, x))[i-1..-1].rjust(32, " ")}"
sleep(0.1)
end
sleep(1)

# -----
# Input
# -----
# just do a simple XOR if binary string arguments passed
if ARGV.size >= 2
width = ARGV.map(&:size).max # work out the longest binary string (for display purposes)
system "clear"
ARGV.each do |binary|
puts binary.rjust(width, " ")
end
puts "-" * width
puts ARGV.map{|x| x.to_i(2)}.reduce(0, :^).to_s(2).rjust(width, "0")
exit
end
# ---------
# Animation
# ---------
# If no arguments passed, show an animation that showcases the XOR operator across 3 inputs
off = 0b00000000000000000000000000000000
on = 0b11111111111111111111111111111111
split = 0b10101010101010101010101010101010
delay = 0.4
# Up To All 1
system "clear"
puts ("%032b" % off)
puts ("%032b" % off) + " XOR"
puts ("%032b" % off) + " XOR"
puts "--------------------------------"
puts "%032b" % (off ^ off ^ off)
sleep delay
system "clear"
puts ("%032b" % on)
puts ("%032b" % off) + " XOR"
puts ("%032b" % off) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ off ^ off)
sleep delay
system "clear"
puts ("%032b" % on)
puts ("%032b" % on) + " XOR"
puts ("%032b" % off) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ on ^ off)
sleep delay
system "clear"
puts ("%032b" % on)
puts ("%032b" % on) + " XOR"
puts ("%032b" % on) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ on ^ on)
sleep delay
# Back To All 0
system "clear"
puts ("%032b" % off)
puts ("%032b" % on) + " XOR"
puts ("%032b" % on) + " XOR"
puts "--------------------------------"
puts "%032b" % (off ^ on ^ on)
sleep delay
system "clear"
puts ("%032b" % off)
puts ("%032b" % off) + " XOR"
puts ("%032b" % on) + " XOR"
puts "--------------------------------"
puts "%032b" % (off ^ off ^ on)
sleep delay
system "clear"
puts ("%032b" % off)
puts ("%032b" % off) + " XOR"
puts ("%032b" % off) + " XOR"
puts "--------------------------------"
puts "%032b" % (off ^ off ^ off)
sleep delay
# Only One 1
system "clear"
puts ("%032b" % on)
puts ("%032b" % off) + " XOR"
puts ("%032b" % off) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ off ^ off)
sleep delay
system "clear"
puts ("%032b" % off)
puts ("%032b" % on) + " XOR"
puts ("%032b" % off) + " XOR"
puts "--------------------------------"
puts "%032b" % (off ^ on ^ off)
sleep delay
system "clear"
puts ("%032b" % off)
puts ("%032b" % off) + " XOR"
puts ("%032b" % on) + " XOR"
puts "--------------------------------"
puts "%032b" % (off ^ off ^ on)
sleep delay
# Majority 1
system "clear"
puts ("%032b" % off)
puts ("%032b" % on) + " XOR"
puts ("%032b" % on) + " XOR"
puts "--------------------------------"
puts "%032b" % (off ^ on ^ on)
sleep delay
system "clear"
puts ("%032b" % on)
puts ("%032b" % off) + " XOR"
puts ("%032b" % on) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ off ^ on)
sleep delay
system "clear"
puts ("%032b" % on)
puts ("%032b" % on) + " XOR"
puts ("%032b" % off) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ on ^ off)
sleep delay
# All 1
system "clear"
puts ("%032b" % on)
puts ("%032b" % on) + " XOR"
puts ("%032b" % on) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ on ^ on)
sleep delay
sleep delay
# Split
system "clear"
puts ("%032b" % on)
puts ("%032b" % on) + " XOR"
puts ("%032b" % split) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ on ^ split)
sleep delay
# Split - Rotate
def rotr(n, x)
mask = 2**32 - 1
right = (x >> n) & mask
left = (x << 32-n) & mask
result = right | left
end
9.times do |i|
system "clear"
puts ("%032b" % on)
puts ("%032b" % on) + " XOR"
puts ("%032b" % rotr(i, split)) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ on ^ rotr(i, split))
sleep delay/2
end
sleep delay
9.times do |i|
system "clear"
puts ("%032b" % on)
puts ("%032b" % off) + " XOR"
puts ("%032b" % rotr(i, split)) + " XOR"
puts "--------------------------------"
puts "%032b" % (on ^ off ^ rotr(i, split))
sleep delay/2
end
sleep delay
9.times do |i|
system "clear"
puts ("%032b" % off)
puts ("%032b" % off) + " XOR"
puts ("%032b" % rotr(i, split)) + " XOR"
puts "--------------------------------"
puts "%032b" % (off ^ off ^ rotr(i, split))
sleep delay/2
end
sleep delay