diff --git a/README.md b/README.md index f6ce37546..c252ad041 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Cairo Verifier +![Cairo Verifier](https://github.com/HerodotusDev/cairo-verifier/assets/46165861/8692dfc1-f267-4c7e-9af0-4ceaeec84207) This document provides steps to build and run the Cairo Verifier. diff --git a/src/common/array_append.cairo b/src/common/array_append.cairo index a54329f60..74aecb46e 100644 --- a/src/common/array_append.cairo +++ b/src/common/array_append.cairo @@ -50,25 +50,21 @@ impl ArrayU32AppendFelt of ArrayAppendTrait { } impl ArrayU32AppendFeltsSpan of ArrayAppendTrait> { - fn append_little_endian(ref self: Array, element: Span) { - let mut i = 0; + fn append_little_endian(ref self: Array, mut element: Span) { loop { - if i == element.len() { - break; + match element.pop_front() { + Option::Some(elem) => self.append_little_endian(*elem), + Option::None => { break; } } - self.append_little_endian(*element[i]); - i += 1; - }; + } } - fn append_big_endian(ref self: Array, element: Span) { - let mut i = 0; + fn append_big_endian(ref self: Array, mut element: Span) { loop { - if i == element.len() { - break; + match element.pop_front() { + Option::Some(elem) => self.append_big_endian(*elem), + Option::None => { break; } } - self.append_big_endian(*element[i]); - i += 1; - }; + } } } diff --git a/src/common/blake2s.cairo b/src/common/blake2s.cairo index 8305b16c9..2bad1f728 100644 --- a/src/common/blake2s.cairo +++ b/src/common/blake2s.cairo @@ -87,15 +87,7 @@ fn blake2s_init() -> blake2s_state { 0x1F83D9AB, 0x5BE0CD19 ]; - let mut buf = ArrayTrait::new(); - let mut i = 0; - loop { - if i == 16 { - break; - } - buf.append(0); - i += 1; - }; + let mut buf = array![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; blake2s_state { h: blake2s_IV, t0: 0, t1: 0, f0: 0, buf: buf, buflen: 0 } } @@ -132,127 +124,85 @@ fn blake2s_compress(mut s: blake2s_state, m: Array) -> blake2s_state { // ROUND function begin - let mut a = 0; - let mut b = 0; - let mut c = 0; - let mut d = 0; - let mut i = 0; - loop { - if i == 8 { - break; - } - if i == 0 { - a = v0; - b = v4; - c = v8; - d = v12; - } else if i == 1 { - a = v1; - b = v5; - c = v9; - d = v13; - } else if i == 2 { - a = v2; - b = v6; - c = v10; - d = v14; - } else if i == 3 { - a = v3; - b = v7; - c = v11; - d = v15; - } else if i == 4 { - a = v0; - b = v5; - c = v10; - d = v15; - } else if i == 5 { - a = v1; - b = v6; - c = v11; - d = v12; - } else if i == 6 { - a = v2; - b = v7; - c = v8; - d = v13; - } else if i == 7 { - a = v3; - b = v4; - c = v9; - d = v14; - }; - - // G function begin - - // a = a + b + m[sigma[r][2*i]] - a = u32_wrapping_add(u32_wrapping_add(a, b), *m_span.at(*sigma[2 * i])); - - d = rotr16(d ^ a); - - // c = c + d - c = u32_wrapping_add(c, d); - - b = rotr12(b ^ c); - - // a = a + b + m[sigma[r][2*i+1]] - a = u32_wrapping_add(u32_wrapping_add(a, b), *m_span.at(*sigma[2 * i + 1])); - - d = rotr8(d ^ a); - - // c = c + d - c = u32_wrapping_add(c, d); - - b = rotr7(b ^ c); - - // G function end - - if i == 0 { - v0 = a; - v4 = b; - v8 = c; - v12 = d; - } else if i == 1 { - v1 = a; - v5 = b; - v9 = c; - v13 = d; - } else if i == 2 { - v2 = a; - v6 = b; - v10 = c; - v14 = d; - } else if i == 3 { - v3 = a; - v7 = b; - v11 = c; - v15 = d; - } else if i == 4 { - v0 = a; - v5 = b; - v10 = c; - v15 = d; - } else if i == 5 { - v1 = a; - v6 = b; - v11 = c; - v12 = d; - } else if i == 6 { - v2 = a; - v7 = b; - v8 = c; - v13 = d; - } else if i == 7 { - v3 = a; - v4 = b; - v9 = c; - v14 = d; - }; - - i += 1; - }; - - // ROUND function end + // 0 - 0,4,8,12 + v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma[0])); + v12 = rotr16(v12 ^ v0); + v8 = u32_wrapping_add(v8, v12); + v4 = rotr12(v4 ^ v8); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma[1])); + v12 = rotr8(v12 ^ v0); + v8 = u32_wrapping_add(v8, v12); + v4 = rotr7(v4 ^ v8); + + // 1 - 1,5,9,13 + v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma[2])); + v13 = rotr16(v13 ^ v1); + v9 = u32_wrapping_add(v9, v13); + v5 = rotr12(v5 ^ v9); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma[3])); + v13 = rotr8(v13 ^ v1); + v9 = u32_wrapping_add(v9, v13); + v5 = rotr7(v5 ^ v9); + + // 2 - 2,6,10,14 + v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma[4])); + v14 = rotr16(v14 ^ v2); + v10 = u32_wrapping_add(v10, v14); + v6 = rotr12(v6 ^ v10); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma[5])); + v14 = rotr8(v14 ^ v2); + v10 = u32_wrapping_add(v10, v14); + v6 = rotr7(v6 ^ v10); + + // 3 - 3,7,11,15 + v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma[6])); + v15 = rotr16(v15 ^ v3); + v11 = u32_wrapping_add(v11, v15); + v7 = rotr12(v7 ^ v11); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma[7])); + v15 = rotr8(v15 ^ v3); + v11 = u32_wrapping_add(v11, v15); + v7 = rotr7(v7 ^ v11); + + // 4 - 0,5,10,15 + v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma[8])); + v15 = rotr16(v15 ^ v0); + v10 = u32_wrapping_add(v10, v15); + v5 = rotr12(v5 ^ v10); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma[9])); + v15 = rotr8(v15 ^ v0); + v10 = u32_wrapping_add(v10, v15); + v5 = rotr7(v5 ^ v10); + + // 5 - 1,6,11,12 + v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma[10])); + v12 = rotr16(v12 ^ v1); + v11 = u32_wrapping_add(v11, v12); + v6 = rotr12(v6 ^ v11); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma[11])); + v12 = rotr8(v12 ^ v1); + v11 = u32_wrapping_add(v11, v12); + v6 = rotr7(v6 ^ v11); + + // 6 - 2,7,8,13 + v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma[12])); + v13 = rotr16(v13 ^ v2); + v8 = u32_wrapping_add(v8, v13); + v7 = rotr12(v7 ^ v8); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma[13])); + v13 = rotr8(v13 ^ v2); + v8 = u32_wrapping_add(v8, v13); + v7 = rotr7(v7 ^ v8); + + // 7 - 3,4,9,14 + v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma[14])); + v14 = rotr16(v14 ^ v3); + v9 = u32_wrapping_add(v9, v14); + v4 = rotr12(v4 ^ v9); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma[15])); + v14 = rotr8(v14 ^ v3); + v9 = u32_wrapping_add(v9, v14); + v4 = rotr7(v4 ^ v9); r += 1; }; diff --git a/src/common/blake2s_u8.cairo b/src/common/blake2s_u8.cairo index 9d46538e9..72962a58a 100644 --- a/src/common/blake2s_u8.cairo +++ b/src/common/blake2s_u8.cairo @@ -88,15 +88,7 @@ fn blake2s_init() -> blake2s_state { 0x1F83D9AB, 0x5BE0CD19 ]; - let mut buf = ArrayTrait::new(); - let mut i = 0; - loop { - if i == 64 { - break; - } - buf.append(0); - i += 1; - }; + let mut buf = array![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; blake2s_state { h: blake2s_IV, t0: 0, t1: 0, f0: 0, buf: buf, buflen: 0 } } @@ -144,125 +136,85 @@ fn blake2s_compress(mut s: blake2s_state, in: Array) -> blake2s_state { // ROUND function begin - let mut a = 0; - let mut b = 0; - let mut c = 0; - let mut d = 0; - let mut i = 0; - loop { - if i == 8 { - break; - } - if i == 0 { - a = v0; - b = v4; - c = v8; - d = v12; - } else if i == 1 { - a = v1; - b = v5; - c = v9; - d = v13; - } else if i == 2 { - a = v2; - b = v6; - c = v10; - d = v14; - } else if i == 3 { - a = v3; - b = v7; - c = v11; - d = v15; - } else if i == 4 { - a = v0; - b = v5; - c = v10; - d = v15; - } else if i == 5 { - a = v1; - b = v6; - c = v11; - d = v12; - } else if i == 6 { - a = v2; - b = v7; - c = v8; - d = v13; - } else if i == 7 { - a = v3; - b = v4; - c = v9; - d = v14; - }; - - // G function begin - - // a = a + b + m[sigma[r][2*i]] - a = u32_wrapping_add(u32_wrapping_add(a, b), *m_span.at(*sigma[2 * i])); - - d = rotr16(d ^ a); - - // c = c + d - c = u32_wrapping_add(c, d); - - b = rotr12(b ^ c); - - // a = a + b + m[sigma[r][2*i+1]] - a = u32_wrapping_add(u32_wrapping_add(a, b), *m_span.at(*sigma[2 * i + 1])); - - d = rotr8(d ^ a); - - // c = c + d - c = u32_wrapping_add(c, d); - - b = rotr7(b ^ c); - - // G function end - - if i == 0 { - v0 = a; - v4 = b; - v8 = c; - v12 = d; - } else if i == 1 { - v1 = a; - v5 = b; - v9 = c; - v13 = d; - } else if i == 2 { - v2 = a; - v6 = b; - v10 = c; - v14 = d; - } else if i == 3 { - v3 = a; - v7 = b; - v11 = c; - v15 = d; - } else if i == 4 { - v0 = a; - v5 = b; - v10 = c; - v15 = d; - } else if i == 5 { - v1 = a; - v6 = b; - v11 = c; - v12 = d; - } else if i == 6 { - v2 = a; - v7 = b; - v8 = c; - v13 = d; - } else if i == 7 { - v3 = a; - v4 = b; - v9 = c; - v14 = d; - }; - - i += 1; - }; + // 0 - 0,4,8,12 + v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma[0])); + v12 = rotr16(v12 ^ v0); + v8 = u32_wrapping_add(v8, v12); + v4 = rotr12(v4 ^ v8); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma[1])); + v12 = rotr8(v12 ^ v0); + v8 = u32_wrapping_add(v8, v12); + v4 = rotr7(v4 ^ v8); + + // 1 - 1,5,9,13 + v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma[2])); + v13 = rotr16(v13 ^ v1); + v9 = u32_wrapping_add(v9, v13); + v5 = rotr12(v5 ^ v9); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma[3])); + v13 = rotr8(v13 ^ v1); + v9 = u32_wrapping_add(v9, v13); + v5 = rotr7(v5 ^ v9); + + // 2 - 2,6,10,14 + v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma[4])); + v14 = rotr16(v14 ^ v2); + v10 = u32_wrapping_add(v10, v14); + v6 = rotr12(v6 ^ v10); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma[5])); + v14 = rotr8(v14 ^ v2); + v10 = u32_wrapping_add(v10, v14); + v6 = rotr7(v6 ^ v10); + + // 3 - 3,7,11,15 + v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma[6])); + v15 = rotr16(v15 ^ v3); + v11 = u32_wrapping_add(v11, v15); + v7 = rotr12(v7 ^ v11); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma[7])); + v15 = rotr8(v15 ^ v3); + v11 = u32_wrapping_add(v11, v15); + v7 = rotr7(v7 ^ v11); + + // 4 - 0,5,10,15 + v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma[8])); + v15 = rotr16(v15 ^ v0); + v10 = u32_wrapping_add(v10, v15); + v5 = rotr12(v5 ^ v10); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma[9])); + v15 = rotr8(v15 ^ v0); + v10 = u32_wrapping_add(v10, v15); + v5 = rotr7(v5 ^ v10); + + // 5 - 1,6,11,12 + v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma[10])); + v12 = rotr16(v12 ^ v1); + v11 = u32_wrapping_add(v11, v12); + v6 = rotr12(v6 ^ v11); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma[11])); + v12 = rotr8(v12 ^ v1); + v11 = u32_wrapping_add(v11, v12); + v6 = rotr7(v6 ^ v11); + + // 6 - 2,7,8,13 + v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma[12])); + v13 = rotr16(v13 ^ v2); + v8 = u32_wrapping_add(v8, v13); + v7 = rotr12(v7 ^ v8); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma[13])); + v13 = rotr8(v13 ^ v2); + v8 = u32_wrapping_add(v8, v13); + v7 = rotr7(v7 ^ v8); + + // 7 - 3,4,9,14 + v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma[14])); + v14 = rotr16(v14 ^ v3); + v9 = u32_wrapping_add(v9, v14); + v4 = rotr12(v4 ^ v9); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma[15])); + v14 = rotr8(v14 ^ v3); + v9 = u32_wrapping_add(v9, v14); + v4 = rotr7(v4 ^ v9); // ROUND function end diff --git a/src/common/tests/test_array_append.cairo b/src/common/tests/test_array_append.cairo index 6ef8961c5..cadd8f2cd 100644 --- a/src/common/tests/test_array_append.cairo +++ b/src/common/tests/test_array_append.cairo @@ -51,3 +51,43 @@ fn test_array_append_le_4() { assert((*result[6]) == 0x89ac0246, 'Invalid value'); assert((*result[7]) == 0x2866b5eb, 'Invalid value'); } + +#[test] +#[available_gas(9999999999)] +fn test_array_append_le_5() { + let value: Array = array![1, 2, 3, 4]; + let mut result = ArrayTrait::::new(); + result.append_little_endian(value.span()); + assert((*result[0]) == 0x1, 'Invalid value'); + assert((*result[1]) == 0x0, 'Invalid value'); + assert((*result[2]) == 0x0, 'Invalid value'); + assert((*result[3]) == 0x0, 'Invalid value'); + assert((*result[4]) == 0x0, 'Invalid value'); + assert((*result[5]) == 0x0, 'Invalid value'); + assert((*result[6]) == 0x0, 'Invalid value'); + assert((*result[7]) == 0x0, 'Invalid value'); + assert((*result[8]) == 0x2, 'Invalid value'); + assert((*result[9]) == 0x0, 'Invalid value'); + assert((*result[10]) == 0x0, 'Invalid value'); + assert((*result[11]) == 0x0, 'Invalid value'); + assert((*result[12]) == 0x0, 'Invalid value'); + assert((*result[13]) == 0x0, 'Invalid value'); + assert((*result[14]) == 0x0, 'Invalid value'); + assert((*result[15]) == 0x0, 'Invalid value'); + assert((*result[16]) == 0x3, 'Invalid value'); + assert((*result[17]) == 0x0, 'Invalid value'); + assert((*result[18]) == 0x0, 'Invalid value'); + assert((*result[19]) == 0x0, 'Invalid value'); + assert((*result[20]) == 0x0, 'Invalid value'); + assert((*result[21]) == 0x0, 'Invalid value'); + assert((*result[22]) == 0x0, 'Invalid value'); + assert((*result[23]) == 0x0, 'Invalid value'); + assert((*result[24]) == 0x4, 'Invalid value'); + assert((*result[25]) == 0x0, 'Invalid value'); + assert((*result[26]) == 0x0, 'Invalid value'); + assert((*result[27]) == 0x0, 'Invalid value'); + assert((*result[28]) == 0x0, 'Invalid value'); + assert((*result[29]) == 0x0, 'Invalid value'); + assert((*result[30]) == 0x0, 'Invalid value'); + assert((*result[31]) == 0x0, 'Invalid value'); +}