fix(alg): sha2-256 sigma functions were wrong
This commit is contained in:
parent
bb81a7dd49
commit
e78dc4a628
2 changed files with 73 additions and 20 deletions
|
@ -18,3 +18,8 @@ apt install binutils-arm-none-eabi gcc-arm-none-eabi # compiler for the target a
|
||||||
apt install ruby # ceedling is the used build system for algorithms-c, and needs to be installed with gem, the ruby package manager
|
apt install ruby # ceedling is the used build system for algorithms-c, and needs to be installed with gem, the ruby package manager
|
||||||
gem install ceedling
|
gem install ceedling
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
For implementing the SHA-2-256 Algorithm, [this](https://sha256algorithm.com/)
|
||||||
|
website was very helpful.
|
||||||
|
|
|
@ -76,7 +76,6 @@ impl Sha2_256Context {
|
||||||
Ok(self.intermediate_hash)
|
Ok(self.intermediate_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BUG: false values at end?
|
|
||||||
fn process_block(&mut self) {
|
fn process_block(&mut self) {
|
||||||
show_internals!({
|
show_internals!({
|
||||||
self.show_internal_state("start processing");
|
self.show_internal_state("start processing");
|
||||||
|
@ -93,10 +92,12 @@ impl Sha2_256Context {
|
||||||
| (self.block[t4 + 3] as u32);
|
| (self.block[t4 + 3] as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: The sigma functions used for initializing W and for calculating the alphabet
|
||||||
|
// variables differ.
|
||||||
for t in 16..SHA2_256_BLOCK_SIZE {
|
for t in 16..SHA2_256_BLOCK_SIZE {
|
||||||
w[t] = Self::sha256_sigma1_1(w[t - 2])
|
w[t] = Self::sha256_sigma1_w(w[t - 2])
|
||||||
.wrapping_add(w[t - 7])
|
.wrapping_add(w[t - 7])
|
||||||
.wrapping_add(Self::sha256_sigma0_1(w[t - 15]))
|
.wrapping_add(Self::sha256_sigma0_w(w[t - 15]))
|
||||||
.wrapping_add(w[t - 16]);
|
.wrapping_add(w[t - 16]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,13 +135,12 @@ impl Sha2_256Context {
|
||||||
println!("Iter {t}");
|
println!("Iter {t}");
|
||||||
});
|
});
|
||||||
|
|
||||||
// BUG: the alphabet values are not being changed correctly?
|
|
||||||
temp1 = h
|
temp1 = h
|
||||||
.wrapping_add(Self::sha256_sigma1_0(e))
|
.wrapping_add(Self::sha256_sigma1(e))
|
||||||
.wrapping_add(Self::sha_ch(e, f, g))
|
.wrapping_add(Self::sha_ch(e, f, g))
|
||||||
.wrapping_add(Self::K[t])
|
.wrapping_add(Self::K[t])
|
||||||
.wrapping_add(w[t]);
|
.wrapping_add(w[t]);
|
||||||
temp2 = Self::sha256_sigma0_0(a).wrapping_add(Self::sha_maj(a, b, c));
|
temp2 = Self::sha256_sigma0(a).wrapping_add(Self::sha_maj(a, b, c));
|
||||||
h = g;
|
h = g;
|
||||||
g = f;
|
g = f;
|
||||||
f = e;
|
f = e;
|
||||||
|
@ -151,6 +151,8 @@ impl Sha2_256Context {
|
||||||
a = temp1.wrapping_add(temp2);
|
a = temp1.wrapping_add(temp2);
|
||||||
|
|
||||||
show_internals!({
|
show_internals!({
|
||||||
|
println!("temp1:\t{temp1:032b} {temp1:08x}");
|
||||||
|
println!("temp2:\t{temp2:032b} {temp2:08x}");
|
||||||
println!("A:\t{a:032b} {a:08x}");
|
println!("A:\t{a:032b} {a:08x}");
|
||||||
println!("B:\t{b:032b} {b:08x}");
|
println!("B:\t{b:032b} {b:08x}");
|
||||||
println!("C:\t{c:032b} {c:08x}");
|
println!("C:\t{c:032b} {c:08x}");
|
||||||
|
@ -180,7 +182,6 @@ impl Sha2_256Context {
|
||||||
|
|
||||||
self.block_idx = 0;
|
self.block_idx = 0;
|
||||||
|
|
||||||
// BUG: something is weird with these hash values, they are almost right?
|
|
||||||
show_internals!({
|
show_internals!({
|
||||||
self.show_internal_state("processing end");
|
self.show_internal_state("processing end");
|
||||||
for (i, h) in self.intermediate_hash.iter().enumerate() {
|
for (i, h) in self.intermediate_hash.iter().enumerate() {
|
||||||
|
@ -255,25 +256,28 @@ impl Sha2_256Context {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sha256_rotr(bits: u32, word: u32) -> u32 {
|
fn sha256_rotr(bits: u32, word: u32) -> u32 {
|
||||||
u32::rotate_right(word, bits)
|
word.rotate_right(bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sha256_sigma0_0(word: u32) -> u32 {
|
/// This is a different function for W
|
||||||
Self::sha256_rotr(2, word) ^ Self::sha256_rotr(13, word) ^ Self::sha256_shr(22, word)
|
fn sha256_sigma0_w(word: u32) -> u32 {
|
||||||
}
|
|
||||||
|
|
||||||
fn sha256_sigma1_0(word: u32) -> u32 {
|
|
||||||
Self::sha256_rotr(6, word) ^ Self::sha256_rotr(11, word) ^ Self::sha256_shr(25, word)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sha256_sigma0_1(word: u32) -> u32 {
|
|
||||||
Self::sha256_rotr(7, word) ^ Self::sha256_rotr(18, word) ^ Self::sha256_shr(3, word)
|
Self::sha256_rotr(7, word) ^ Self::sha256_rotr(18, word) ^ Self::sha256_shr(3, word)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sha256_sigma1_1(word: u32) -> u32 {
|
/// This is a different function for W
|
||||||
|
fn sha256_sigma1_w(word: u32) -> u32 {
|
||||||
Self::sha256_rotr(17, word) ^ Self::sha256_rotr(19, word) ^ Self::sha256_shr(10, word)
|
Self::sha256_rotr(17, word) ^ Self::sha256_rotr(19, word) ^ Self::sha256_shr(10, word)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: these do not use shift right for the last internal variable!
|
||||||
|
fn sha256_sigma0(word: u32) -> u32 {
|
||||||
|
Self::sha256_rotr(2, word) ^ Self::sha256_rotr(13, word) ^ Self::sha256_rotr(22, word)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sha256_sigma1(word: u32) -> u32 {
|
||||||
|
Self::sha256_rotr(6, word) ^ Self::sha256_rotr(11, word) ^ Self::sha256_rotr(25, word)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sha_ch(x: u32, y: u32, z: u32) -> u32 {
|
fn sha_ch(x: u32, y: u32, z: u32) -> u32 {
|
||||||
(x & (y ^ z)) ^ z
|
(x & (y ^ z)) ^ z
|
||||||
|
@ -309,7 +313,7 @@ mod debug {
|
||||||
T: core::fmt::Debug + core::fmt::LowerHex,
|
T: core::fmt::Debug + core::fmt::LowerHex,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "[\n")?;
|
writeln!(f, "[")?;
|
||||||
for (i, t) in self.0.iter().enumerate() {
|
for (i, t) in self.0.iter().enumerate() {
|
||||||
write!(f, "0x{t:02x}")?;
|
write!(f, "0x{t:02x}")?;
|
||||||
if i < self.0.len() - 1 {
|
if i < self.0.len() - 1 {
|
||||||
|
@ -337,6 +341,7 @@ mod debug {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "show_internals")]
|
#[cfg(feature = "show_internals")]
|
||||||
|
#[allow(unused)]
|
||||||
use debug::*;
|
use debug::*;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -345,6 +350,31 @@ mod test {
|
||||||
use assert_hex::*;
|
use assert_hex::*;
|
||||||
use pretty_assertions::{assert_eq, assert_ne};
|
use pretty_assertions::{assert_eq, assert_ne};
|
||||||
|
|
||||||
|
macro_rules! assert_eq_bin {
|
||||||
|
($left:expr, $right:expr $(,)?) => ({
|
||||||
|
match (&$left, &$right) {
|
||||||
|
(left_val, right_val) => {
|
||||||
|
if !(*left_val == *right_val) {
|
||||||
|
panic!(r#"assertion `left == right` failed
|
||||||
|
left: {:b}
|
||||||
|
right: {:b}"#, &*left_val, &*right_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
($left:expr, $right:expr, $($arg:tt)+) => ({
|
||||||
|
match (&($left), &($right)) {
|
||||||
|
(left_val, right_val) => {
|
||||||
|
if !(*left_val == *right_val) {
|
||||||
|
panic!(r#"assertion `left == right` failed: {}
|
||||||
|
left: {:b}
|
||||||
|
right: {:b}"#, format_args!($($arg)+), &*left_val, &*right_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const TEST_VALUES: &[(&str, Digest256)] = &[
|
const TEST_VALUES: &[(&str, Digest256)] = &[
|
||||||
(
|
(
|
||||||
"AAAA",
|
"AAAA",
|
||||||
|
@ -363,7 +393,7 @@ mod test {
|
||||||
];
|
];
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check() {
|
fn test_sha256_check() {
|
||||||
let mut dig;
|
let mut dig;
|
||||||
for (input, expected_output) in TEST_VALUES.iter().copied() {
|
for (input, expected_output) in TEST_VALUES.iter().copied() {
|
||||||
dig = sha2_256_oneshot(input.as_bytes()).unwrap();
|
dig = sha2_256_oneshot(input.as_bytes()).unwrap();
|
||||||
|
@ -376,4 +406,22 @@ mod test {
|
||||||
assert_eq_hex!(dig, expected_output)
|
assert_eq_hex!(dig, expected_output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sha256_sigma0() {
|
||||||
|
let a = 0b01101010000010011110011001100111;
|
||||||
|
assert_eq_bin!(
|
||||||
|
Sha2_256Context::sha256_sigma0(a),
|
||||||
|
0b11001110001000001011010001111110
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sha256_sigma1() {
|
||||||
|
let a = 0b01010001000011100101001001111111;
|
||||||
|
assert_eq_bin!(
|
||||||
|
Sha2_256Context::sha256_sigma1(a),
|
||||||
|
0b00110101100001110010011100101011
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue