From 342a217238f19659d7c551367ec3826b03ac0e43 Mon Sep 17 00:00:00 2001 From: petscheit Date: Wed, 16 Oct 2024 15:08:26 +0200 Subject: [PATCH] chore: fix comments --- src/basic_field_ops.cairo | 1 + src/hash_to_field.cairo | 34 ++++++++++++++----- src/sha.cairo | 13 ++++++- .../fustat_programs/test_hash_to_field.cairo | 15 ++++---- tests/fustat_programs/test_sha256.cairo | 1 + 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/basic_field_ops.cairo b/src/basic_field_ops.cairo index 88e2e26..8ea50f9 100644 --- a/src/basic_field_ops.cairo +++ b/src/basic_field_ops.cairo @@ -6,6 +6,7 @@ const POW_2_32_252 = 0x100000000; const POW_2_64_252 = 0x10000000000000000; // Compute u512 mod p, where u512 = high * 2^256 + low +// Each high/low limb is 32 bits big and passed in BE func u512_mod_p{range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*}( low: (v0: felt, v1: felt, v2: felt, v3: felt, v4: felt, v5: felt, v6: felt, v7: felt), high: (v0: felt, v1: felt, v2: felt, v3: felt, v4: felt, v5: felt, v6: felt, v7: felt), diff --git a/src/hash_to_field.cairo b/src/hash_to_field.cairo index a80f8c7..d96dba1 100644 --- a/src/hash_to_field.cairo +++ b/src/hash_to_field.cairo @@ -180,9 +180,10 @@ namespace HashToField32 { // - msg: a byte string containing the message to hash, chunked in big-endian 4-bytes // - msg_bytes_len: length of the message in bytes // - count: the number of field elements to output + // - ext_degree: the degree of the extension field // // Returns: - // - fields: an array of field elements [u_0, ..., u_(count - 1)] + // - fields: an 2d array of field elements in the following format [[f_n; ext_degree]; count]] func hash_to_field{ range_check_ptr, bitwise_ptr: BitwiseBuiltin*, @@ -191,13 +192,13 @@ namespace HashToField32 { mul_mod_ptr: ModBuiltin*, sha256_ptr: felt*, pow2_array: felt*, - }(msg: felt*, msg_bytes_len: felt, count: felt) -> (fields: UInt384**) { + }(msg: felt*, msg_bytes_len: felt, count: felt, ext_degree: felt) -> (fields: UInt384**) { alloc_locals; - let n_bytes = count * CURVE_M * CURVE_L; + let n_bytes = count * ext_degree * CURVE_L; let (result) = expand_msg_xmd(msg=msg, msg_bytes_len=msg_bytes_len, n_bytes=n_bytes); let (result_fields: UInt384**) = alloc(); - with result_fields { + with result_fields, ext_degree { hash_to_field_inner(expanded_msg=result, count=count, index=0); } @@ -211,6 +212,7 @@ namespace HashToField32 { add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*, pow2_array: felt*, + ext_degree: felt, result_fields: UInt384**, }(expanded_msg: felt*, count: felt, index: felt) { alloc_locals; @@ -219,9 +221,9 @@ namespace HashToField32 { return (); } - let offset = index * CURVE_L_IN_FELTS * CURVE_M; + let offset = index * CURVE_L_IN_FELTS * ext_degree; let (fields: UInt384*) = alloc(); - with fields { + with fields, ext_degree { hash_to_field_inner_inner( expanded_msg=expanded_msg, count_index=index, degree_index=0, offset=offset ); @@ -232,20 +234,25 @@ namespace HashToField32 { } // Innermost recursive function for hash_to_field - // Runs CURVE_M times (degree of the extension field) + // Runs ext_degree times func hash_to_field_inner_inner{ range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*, pow2_array: felt*, + ext_degree: felt, fields: UInt384*, }(expanded_msg: felt*, count_index: felt, degree_index: felt, offset: felt) { - if (degree_index == CURVE_M) { + if (degree_index == ext_degree) { return (); } let (result) = _u512_mod_p(expanded_msg + offset); - // %{ print(hex(ids.result.d3 * 2**288 + ids.result.d2 * 2**192 + ids.result.d1 * 2**96 + ids.result.d0)) %} + // %{ + // from garaga.hints.io import bigint_pack + // result = bigint_pack(ids.result, 4, 2**96) + // print(hex(result)) + // %} assert fields[degree_index] = result; return hash_to_field_inner_inner( @@ -257,6 +264,10 @@ namespace HashToField32 { } // Converts a 512-bit byte array to UInt384 and calls u512_mod_p + // Inputs: + // value: felt* - an array of 32bit BE chunks. Must have a length of 16. + // Outputs: + // result: UInt384 - The result of (value mod p), where p is the BLS12-381 field modulus func _u512_mod_p{ range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, @@ -293,6 +304,11 @@ namespace HashToField32 { } // XORs two 256-bit hashes + // Inputs: + // hash_a: felt* - an array of 32bit BE chunks. Must have a length of 8. + // hash_b: felt* - an array of 32bit BE chunks. Must have a length of 8. + // Outputs: + // result: felt* - XOR of the input, as 32bit BE chunks with length 8. func _xor_hash_segments{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}( hash_a: felt*, hash_b: felt* ) -> felt* { diff --git a/src/sha.cairo b/src/sha.cairo index 4551f8a..c8293de 100644 --- a/src/sha.cairo +++ b/src/sha.cairo @@ -21,7 +21,12 @@ namespace SHA256 { return (); } - func hash_pair{range_check_ptr, sha256_ptr: felt*, pow2_array: felt*}(input: felt*) -> ( + // Computes the SHA256 hash of a 64 byte input + // Inputs: + // input: felt* - the 64 byte input, chunked into 32bit BE chunks. Must have a length of 16. + // Outputs: + // output: felt* - an array of 32bit BE chunks. Must have a length of 8. + func hash_64{range_check_ptr, sha256_ptr: felt*, pow2_array: felt*}(input: felt*) -> ( output: felt* ) { alloc_locals; @@ -29,6 +34,12 @@ namespace SHA256 { return (output=output); } + // Computes the SHA256 hash of an arbitrary length of bytes + // Inputs: + // input: felt* - the input bytes, chunked into 32bit BE chunks. + // n_bytes: felt - the number of bytes in the input + // Outputs: + // output: felt* - an array of 32bit BE chunks. Must have a length of 8. func hash_bytes{range_check_ptr, sha256_ptr: felt*, pow2_array: felt*}( input: felt*, n_bytes: felt ) -> (output: felt*) { diff --git a/tests/fustat_programs/test_hash_to_field.cairo b/tests/fustat_programs/test_hash_to_field.cairo index 5b08e2e..6ccf984 100644 --- a/tests/fustat_programs/test_hash_to_field.cairo +++ b/tests/fustat_programs/test_hash_to_field.cairo @@ -44,22 +44,19 @@ func test_32_bytes_msg{ low=0x135aa063454c6023e1fbafd896f89df9, high=0x18b90e7987b9393d878786da78fa13fd ); let (chunks) = HashUtils.chunk_uint256(value); - let (res) = HashToField32.hash_to_field(chunks, 32, 2); + let (res) = HashToField32.hash_to_field(chunks, 32, 2, 2); let f0 = res[0][0]; let f1 = res[0][1]; let f2 = res[1][0]; let f3 = res[1][1]; %{ - f0 = ids.f0.d3 * 2**288 + ids.f0.d2 * 2**192 + ids.f0.d1 * 2**96 + ids.f0.d0 - f1 = ids.f1.d3 * 2**288 + ids.f1.d2 * 2**192 + ids.f1.d1 * 2**96 + ids.f1.d0 - f2 = ids.f2.d3 * 2**288 + ids.f2.d2 * 2**192 + ids.f2.d1 * 2**96 + ids.f2.d0 - f3 = ids.f3.d3 * 2**288 + ids.f3.d2 * 2**192 + ids.f3.d1 * 2**96 + ids.f3.d0 + from garaga.hints.io import bigint_pack - assert f0 == 0xa1d5f7f60126ba84c5a337f4e9ae2d02ef018a7fd34c6eff78b3bcc327d8ca8f28ed9a9344b3cef5b6946d0078d34f3 - assert f1 == 0xe7f6f005fa2404be24f13fc6bf9facabc9f7b01d4a0fa1df8695251163c27437afccf0d3eb4e611fe8dd14bcd1bb881 - assert f2 == 0x184fd90d987275be14e967e4a4ee0e963544e6694c88d36358a05f0fb45ae538a0e3b687126e0962a40a3cdfa899d0aa - assert f3 == 0xd7d91409c8b0ed8914cc0c877eb255e05135240e28835ade65557b69b6b34b18fe99801702311eb0e1328e4de7ea38b + assert bigint_pack(ids.f0, 4, 2**96) == 0xa1d5f7f60126ba84c5a337f4e9ae2d02ef018a7fd34c6eff78b3bcc327d8ca8f28ed9a9344b3cef5b6946d0078d34f3 + assert bigint_pack(ids.f1, 4, 2**96) == 0xe7f6f005fa2404be24f13fc6bf9facabc9f7b01d4a0fa1df8695251163c27437afccf0d3eb4e611fe8dd14bcd1bb881 + assert bigint_pack(ids.f2, 4, 2**96) == 0x184fd90d987275be14e967e4a4ee0e963544e6694c88d36358a05f0fb45ae538a0e3b687126e0962a40a3cdfa899d0aa + assert bigint_pack(ids.f3, 4, 2**96) == 0xd7d91409c8b0ed8914cc0c877eb255e05135240e28835ade65557b69b6b34b18fe99801702311eb0e1328e4de7ea38b %} return (); } diff --git a/tests/fustat_programs/test_sha256.cairo b/tests/fustat_programs/test_sha256.cairo index b9e8a1b..93e1c23 100644 --- a/tests/fustat_programs/test_sha256.cairo +++ b/tests/fustat_programs/test_sha256.cairo @@ -49,6 +49,7 @@ func run_test{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, sha256_ptr: felt*, local expected: Uint256; %{ import hashlib + # This function chunks from MSB to LSB def hex_to_chunks_32(hex_string: str): # Remove '0x' prefix if present