Last active
October 7, 2023 10:59
-
-
Save GregTonoski/04b679cc6658fb8954fa28619891a8df to your computer and use it in GitHub Desktop.
Calculate sha256 checksum for hex string input by user
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# sha256.sh: calculate sha256 checksum for hex string input by user. Hex string must be shorter than 110 nibbles (or 440 bits). | |
# Example: | |
# $ BIP39-XOR.sh 000ffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364139 | |
fn_right_rotate_32(){ | |
FN_RIGHT_ROTATE_32_RESULT=0 | |
FN_RIGHT_ROTATE_32_RESULT=$(( (${1} / 2 ** ${2}) + (${1} % 2 ** ${2}) * 2 ** (32 - ${2}) )) | |
} | |
fn_right_shift_32(){ | |
FN_RIGHT_SHIFT_32_RESULT=0 | |
FN_RIGHT_SHIFT_32_RESULT=$(( ${1} >> ${2} )) | |
} | |
fn_string_length () { | |
CHAR_COUNT=0 | |
temp_string="" | |
while [[ "${temp_string}" != "${1}" ]] ; do | |
CHAR_COUNT=$(( ${CHAR_COUNT} + 1 )) | |
printf -v temp_string "%.*s" "${CHAR_COUNT}" "${1}" | |
done | |
} | |
export LC_ALL=C | |
CHAR_COUNT=0 | |
fn_string_length $1 | |
if (( ${CHAR_COUNT} > 110 )) ; then | |
echo "ERROR: hex string is longer than 110 characters. Shorter hex strings are accepted only in this version of the program." | |
exit 1 | |
fi | |
if (( ${CHAR_COUNT} == 0)) ; then | |
echo "ERROR: There isn't any hex string read by the program." | |
exit 2 | |
fi | |
BITS_IN_NIBBLE=4 | |
CHUNK="" | |
p1=0 | |
p2=0 | |
p3=0 | |
s0=0 | |
s1=0 | |
w=0 | |
w_index=0 | |
ch=0 | |
temp1=0 | |
temp2=0 | |
maj=0 | |
a=0 | |
b=0 | |
c=0 | |
d=0 | |
e=0 | |
f=0 | |
g=0 | |
h=0 | |
bits_count=0 | |
sha256_word=0 | |
temp_name="" | |
temp_sum=0 | |
SHA2_WORDS0=$((0x6a09e667)) | |
SHA2_WORDS1=$((0xbb67ae85)) | |
SHA2_WORDS2=$((0x3c6ef372)) | |
SHA2_WORDS3=$((0xa54ff53a)) | |
SHA2_WORDS4=$((0x510e527f)) | |
SHA2_WORDS5=$((0x9b05688c)) | |
SHA2_WORDS6=$((0x1f83d9ab)) | |
SHA2_WORDS7=$((0x5be0cd19)) | |
KL0=$((0x428a2f98)) | |
KL1=$((0x71374491)) | |
KL2=$((0xb5c0fbcf)) | |
KL3=$((0xe9b5dba5)) | |
KL4=$((0x3956c25b)) | |
KL5=$((0x59f111f1)) | |
KL6=$((0x923f82a4)) | |
KL7=$((0xab1c5ed5)) | |
KL8=$((0xd807aa98)) | |
KL9=$((0x12835b01)) | |
KL10=$((0x243185be)) | |
KL11=$((0x550c7dc3)) | |
KL12=$((0x72be5d74)) | |
KL13=$((0x80deb1fe)) | |
KL14=$((0x9bdc06a7)) | |
KL15=$((0xc19bf174)) | |
KL16=$((0xe49b69c1)) | |
KL17=$((0xefbe4786)) | |
KL18=$((0x0fc19dc6)) | |
KL19=$((0x240ca1cc)) | |
KL20=$((0x2de92c6f)) | |
KL21=$((0x4a7484aa)) | |
KL22=$((0x5cb0a9dc)) | |
KL23=$((0x76f988da)) | |
KL24=$((0x983e5152)) | |
KL25=$((0xa831c66d)) | |
KL26=$((0xb00327c8)) | |
KL27=$((0xbf597fc7)) | |
KL28=$((0xc6e00bf3)) | |
KL29=$((0xd5a79147)) | |
KL30=$((0x06ca6351)) | |
KL31=$((0x14292967)) | |
KL32=$((0x27b70a85)) | |
KL33=$((0x2e1b2138)) | |
KL34=$((0x4d2c6dfc)) | |
KL35=$((0x53380d13)) | |
KL36=$((0x650a7354)) | |
KL37=$((0x766a0abb)) | |
KL38=$((0x81c2c92e)) | |
KL39=$((0x92722c85)) | |
KL40=$((0xa2bfe8a1)) | |
KL41=$((0xa81a664b)) | |
KL42=$((0xc24b8b70)) | |
KL43=$((0xc76c51a3)) | |
KL44=$((0xd192e819)) | |
KL45=$((0xd6990624)) | |
KL46=$((0xf40e3585)) | |
KL47=$((0x106aa070)) | |
KL48=$((0x19a4c116)) | |
KL49=$((0x1e376c08)) | |
KL50=$((0x2748774c)) | |
KL51=$((0x34b0bcb5)) | |
KL52=$((0x391c0cb3)) | |
KL53=$((0x4ed8aa4a)) | |
KL54=$((0x5b9cca4f)) | |
KL55=$((0x682e6ff3)) | |
KL56=$((0x748f82ee)) | |
KL57=$((0x78a5636f)) | |
KL58=$((0x84c87814)) | |
KL59=$((0x8cc70208)) | |
KL60=$((0x90befffa)) | |
KL61=$((0xa4506ceb)) | |
KL62=$((0xbef9a3f7)) | |
KL63=$((0xc67178f2)) | |
bits_count=$(( ${#1} * ${BITS_IN_NIBBLE} )) | |
for (( i=$(( ${bits_count} + 8 )) ; i < $(( 512 - 64)) ; i=${i}+${BITS_IN_NIBBLE} )); do | |
printf -v "CHUNK" "%s0" "${CHUNK}" | |
done | |
printf -v "CHUNK" "%s80%s%016X" "${1}" "${CHUNK}" "${bits_count}" | |
for ((count=0; count < 16; count++)); do | |
temp_name="w${count}" | |
printf -v ${temp_name} "%d" $((16#${CHUNK:$count*8:8})) | |
done | |
for ((count = 16; count < 64; count++)); do | |
w_index=$((count - 15)) | |
eval "w=\$w${w_index}" | |
fn_right_rotate_32 ${w} 7 | |
p1=${FN_RIGHT_ROTATE_32_RESULT} | |
fn_right_rotate_32 ${w} 18 | |
p2=${FN_RIGHT_ROTATE_32_RESULT} | |
fn_right_shift_32 ${w} 3 | |
p3=${FN_RIGHT_SHIFT_32_RESULT} | |
s0=$(( p1 ^ p2 ^ p3 )) | |
w_index=$((count - 2)) | |
eval "w=\$w${w_index}" | |
fn_right_rotate_32 ${w} 17 | |
p1=${FN_RIGHT_ROTATE_32_RESULT} | |
fn_right_rotate_32 ${w} 19 | |
p2=${FN_RIGHT_ROTATE_32_RESULT} | |
fn_right_shift_32 ${w} 10 | |
p3=${FN_RIGHT_SHIFT_32_RESULT} | |
s1=$(( p1 ^ p2 ^ p3 )) | |
w_index=$((count - 16 )) | |
eval "w=\$w${w_index}" | |
temp_name="w${count}" | |
printf -v ${temp_name} "%d" $(( ${w} + ${s0} )) | |
w_index=$((count - 7 )) | |
eval "w=\$w${w_index}" | |
eval "temp_sum=\$${temp_name}" | |
temp_name="w${count}" | |
printf -v ${temp_name} "%d" $(( (${temp_sum} + ${w} + ${s1}) % 2 ** 32 )) | |
done | |
a=${SHA2_WORDS0} | |
b=${SHA2_WORDS1} | |
c=${SHA2_WORDS2} | |
d=${SHA2_WORDS3} | |
e=${SHA2_WORDS4} | |
f=${SHA2_WORDS5} | |
g=${SHA2_WORDS6} | |
h=${SHA2_WORDS7} | |
for ((round = 0; round < 64 ; round++)); do | |
fn_right_rotate_32 ${e} 6 | |
p1=${FN_RIGHT_ROTATE_32_RESULT} | |
fn_right_rotate_32 ${e} 11 | |
p2=${FN_RIGHT_ROTATE_32_RESULT} | |
fn_right_rotate_32 ${e} 25 | |
p3=${FN_RIGHT_ROTATE_32_RESULT} | |
s1=$(( p1 ^ p2 ^ p3 )) | |
ch=$(( ( ( ${e} & ${f} ) ^ (~${e} & ${g}) ) % 2 ** 32 )) | |
eval "KLround=\$KL${round}" | |
eval "w=\$w${round}" | |
temp1=$(( ( ${h} + ${s1} + ${ch} + ${KLround} + ${w} ) % 2 ** 32 )) | |
fn_right_rotate_32 ${a} 2 | |
p1=${FN_RIGHT_ROTATE_32_RESULT} | |
fn_right_rotate_32 ${a} 13 | |
p2=${FN_RIGHT_ROTATE_32_RESULT} | |
fn_right_rotate_32 ${a} 22 | |
p3=${FN_RIGHT_ROTATE_32_RESULT} | |
s0=$(( p1 ^ p2 ^ p3 )) | |
maj=$(( ( ( ${a} & ${b} ) ^ ( ${a} & ${c} ) ^ ( ${b} & ${c} ) ) % 2 ** 32 )) | |
temp2=$(( (s0 + maj) % 2 ** 32 )) | |
h=${g} | |
g=${f} | |
f=${e} | |
e=$(( ( ${d} + ${temp1} ) % 2 ** 32 )) | |
d=${c} | |
c=${b} | |
b=${a} | |
a=$(( ( ${temp1} + ${temp2} ) % 2 ** 32 )) | |
done | |
SHA2_WORDS0=$(( ( ${SHA2_WORDS0} + ${a} ) % 2 ** 32 )) | |
SHA2_WORDS1=$(( ( ${SHA2_WORDS1} + ${b} ) % 2 ** 32 )) | |
SHA2_WORDS2=$(( ( ${SHA2_WORDS2} + ${c} ) % 2 ** 32 )) | |
SHA2_WORDS3=$(( ( ${SHA2_WORDS3} + ${d} ) % 2 ** 32 )) | |
SHA2_WORDS4=$(( ( ${SHA2_WORDS4} + ${e} ) % 2 ** 32 )) | |
SHA2_WORDS5=$(( ( ${SHA2_WORDS5} + ${f} ) % 2 ** 32 )) | |
SHA2_WORDS6=$(( ( ${SHA2_WORDS6} + ${g} ) % 2 ** 32 )) | |
SHA2_WORDS7=$(( ( ${SHA2_WORDS7} + ${h} ) % 2 ** 32 )) | |
FN_SHA256_RESULT="" | |
for (( i=0 ; i < 8; i=i+1 )); do | |
eval "sha256_word=\$SHA2_WORDS${i}" | |
printf -v "FN_SHA256_RESULT" "%s%08X" "${FN_SHA256_RESULT}" "${sha256_word}" | |
done | |
echo ${FN_SHA256_RESULT} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment