in3rsha/sha256-animation · error

We only operate on 32-bit words in SHA-256. Your x is #{ARGV

Error message

We only operate on 32-bit words in SHA-256. Your x is #{ARGV[0].size} bits.

What it means

rotr.rb is a terminal animation of the 32-bit rotate-right (ROTR) operation used throughout SHA-256. It reads x from ARGV[0] via to_i(2), but first rejects any first argument longer than 32 characters, because SHA-256 words are exactly 32 bits. The check tests raw string length, not parsed bit width — so the two characters of an 0b prefix, leading zeros, or stray spaces all count toward the limit.

Source

Thrown at rotr.rb:23

  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

View on GitHub (pinned to 871e976d69)

Solutions

  1. Trim x to its lowest 32 bits before passing it (x & 0xFFFFFFFF), or drop high bits from the left
  2. Drop the 0b prefix when invoking the CLI — its 2 characters count against the 32-character limit, silently costing 2 bits of width
  3. Compare against the built-in default word 11111111000000001111111100000000 (exactly 32 chars) to sanity-check length
  4. Keep the rotation amount n (ARGV[1]) a plain decimal integer — it is independent of this width check

Example fix

# before
ruby rotr.rb 111111110000000011111111000000001    # 33 bits -> rejected
ruby rotr.rb 0b11111111000000001111111100000000  # prefix counted -> rejected

# after
ruby rotr.rb 11111111000000001111111100000000     # exactly 32 bits, no prefix
Defensive patterns

Strategy: validation

Validate before calling

x_arg = ARGV[0]
raise ArgumentError, 'x must fit a 32-bit word' unless x_arg.nil? || x_arg.delete_prefix('0b').size <= 32
system('ruby', 'rotr.rb', x_arg, '8')

Type guard

def fits_word32?(arg)
  arg.nil? || arg.to_s.delete_prefix('0b').delete(' ').size <= 32
end

Try / catch

begin
  ARGV.replace([x_str, '8'])
  load 'rotr.rb'
rescue SystemExit
  warn 'rotr.rb rejected x (argument longer than 32 characters)'
end

Prevention

When it happens

Trigger: ruby rotr.rb 111111110000000011111111000000001 (33 bits). Also a false positive: ruby rotr.rb 0b11111111000000001111111100000000 is a valid 32-bit word, but the prefix makes ARGV[0].size 34, so it is rejected even though to_i(2) would parse it correctly.

Common situations: Experimenting with words wider than 32 bits after computing message-schedule or compression values in irb (SHA-256 words are 32-bit, but intermediate big integers are not); passing 64-bit values; including the 0b prefix and tripping the undocumented character-count quirk.

Related errors


AI-assisted analysis of in3rsha/sha256-animation@871e976d69 (2026-08-23). Data as JSON: /api/errors/1a99d2bbc91b8d18. Report an issue: GitHub.