pub fn read_last_fri_layer(ctx: & mut Vec<Uint256>) {
    let fri_last_layer_deg_bound = ctx[map::MM_FRI_LAST_LAYER_DEG_BOUND].clone();
    let last_layer_idx: usize = uint256_ops::to_usize(&ctx[map::MM_CHANNEL]);
    //let last_layer_idx = ctx[channel_idx];
    let mut bad_input = 0;

    let prime_minus_one = prime_field::get_k_modulus() - prime_field::get_one_val();
    let channel_idx = 1 + map::MM_CHANNEL;

     // Make sure all the values are valid field elements.
    let last_layer_end = last_layer_idx + uint256_ops::to_usize( &fri_last_layer_deg_bound );
    let mut coefs_idx = last_layer_idx;
    while coefs_idx < last_layer_end {
        if ctx[coefs_idx] > prime_minus_one {
            bad_input = 1;
            break;
        }
        coefs_idx += 1;
    }

    // Copy the digest to the proof area
    // (store it before the coefficients - this is done because
    // keccak256 needs all data to be consecutive),
    // then hash and place back in digest_idx.
    let new_digest_idx = last_layer_idx - 1;
    let digest_idx = channel_idx + 1;
    // Overwriting the proof to minimize copying of data.
    ctx[new_digest_idx] = ctx[digest_idx].clone();

     // prng.digest := keccak256(digest||lastLayerCoefs).
     // Hash the sibling data
    let mut combined_data: Vec<u8> = vec![0; 32*(last_layer_end+2 - new_digest_idx)];
    for i in new_digest_idx..=last_layer_end+1 {
        let bytes = uint256_ops::to_fixed_bytes( &ctx[i] );
        for j in 0..bytes.len() {
            combined_data[ 32*(i-new_digest_idx) + j] = bytes[j];
        }
    }
    ctx[digest_idx] = uint256_ops::keccak_256(&combined_data);

    // prng.counter := 0.
    ctx[channel_idx + 2] = uint256_ops::get_uint256("0");

    // Note: proof pointer is not incremented until this point.
    ctx[channel_idx] = uint256_ops::from_usize(last_layer_end);

    //Invalid field element
    assert!( bad_input == 0 );
    ctx[map::MM_FRI_LAST_LAYER_PTR] = uint256_ops::from_usize(last_layer_idx);
}
/*
    Reads the last FRI layer (i.e. the polynomial's coefficients) from the channel.
    This differs from standard reading of channel field elements in several ways:
    -- The digest is updated by hashing it once with all coefficients simultaneously, rather than
        iteratively one by one.
    -- The coefficients are kept in Montgomery form, as is the case throughout the FRI
        computation.
    -- The coefficients are not actually read and copied elsewhere, but rather only a pointer to
        their location in the channel is stored.
*/
Reads the last FRI layer  from the channel.
This differs from standard reading of channel field elements in several ways:
The digest is updated by hashing it once with all coefficients simultaneously, rather than
iteratively one by one.
The coefficients are kept in Montgomery form, as is the case throughout the FRI
computation.
The coefficients are not actually read and copied elsewhere, but rather only a pointer to
their location in the channel is stored.
Reads the last FRI layer from the channel . This differs from standard reading of channel field elements in several ways : The digest is updated by hashing it once with all coefficients simultaneously rather than iteratively one by one . The coefficients are kept in Montgomery form as is the case throughout the FRI computation . The coefficients are not actually read and copied elsewhere but rather only a pointer to their location in the channel is stored .
pub fn read_last_fri_layer(ctx: & mut Vec<Uint256>) {
    let fri_last_layer_deg_bound = ctx[map::MM_FRI_LAST_LAYER_DEG_BOUND].clone();
    let last_layer_idx: usize = uint256_ops::to_usize(&ctx[map::MM_CHANNEL]);
    //let last_layer_idx = ctx[channel_idx];
    let mut bad_input = 0;
    let prime_minus_one = prime_field::get_k_modulus() - prime_field::get_one_val();
    let channel_idx = 1 + map::MM_CHANNEL;
     // Make sure all the values are valid field elements.
    let last_layer_end = last_layer_idx + uint256_ops::to_usize( &fri_last_layer_deg_bound );
    let mut coefs_idx = last_layer_idx;
    while coefs_idx < last_layer_end {
        if ctx[coefs_idx] > prime_minus_one {
            bad_input = 1;
            break;
        }
        coefs_idx += 1;
    }
    // Copy the digest to the proof area
    // (store it before the coefficients - this is done because
    // keccak256 needs all data to be consecutive),
    // then hash and place back in digest_idx.
    let new_digest_idx = last_layer_idx - 1;
    let digest_idx = channel_idx + 1;
    // Overwriting the proof to minimize copying of data.
    ctx[new_digest_idx] = ctx[digest_idx].clone();
     // prng.digest := keccak256(digest||lastLayerCoefs).
     // Hash the sibling data
    let mut combined_data: Vec<u8> = vec![0; 32*(last_layer_end+2 - new_digest_idx)];
    for i in new_digest_idx..=last_layer_end+1 {
        let bytes = uint256_ops::to_fixed_bytes( &ctx[i] );
        for j in 0..bytes.len() {
            combined_data[ 32*(i-new_digest_idx) + j] = bytes[j];
        }
    }
    ctx[digest_idx] = uint256_ops::keccak_256(&combined_data);
    // prng.counter := 0.
    ctx[channel_idx + 2] = uint256_ops::get_uint256("0");
    // Note: proof pointer is not incremented until this point.
    ctx[channel_idx] = uint256_ops::from_usize(last_layer_end);
    //Invalid field element
    assert!( bad_input == 0 );
    ctx[map::MM_FRI_LAST_LAYER_PTR] = uint256_ops::from_usize(last_layer_idx);
}
pub fn read_last_fri_layer ( ctx : & mut Vec < Uint256 > ) { let fri_last_layer_deg_bound = ctx [ map :: MM_FRI_LAST_LAYER_DEG_BOUND ] . clone ( ) ; let last_layer_idx : usize = uint256_ops :: to_usize ( & ctx [ map :: MM_CHANNEL ] ) ; //let last_layer_idx = ctx[channel_idx]; let mut bad_input = 0 ; let prime_minus_one = prime_field :: get_k_modulus ( ) - prime_field :: get_one_val ( ) ; let channel_idx = 1 + map :: MM_CHANNEL ; // Make sure all the values are valid field elements. let last_layer_end = last_layer_idx + uint256_ops :: to_usize ( & fri_last_layer_deg_bound ) ; let mut coefs_idx = last_layer_idx ; while coefs_idx < last_layer_end { if ctx [ coefs_idx ] > prime_minus_one { bad_input = 1 ; break ; } coefs_idx += 1 ; } // Copy the digest to the proof area // (store it before the coefficients - this is done because // keccak256 needs all data to be consecutive), // then hash and place back in digest_idx. let new_digest_idx = last_layer_idx - 1 ; let digest_idx = channel_idx + 1 ; // Overwriting the proof to minimize copying of data. ctx [ new_digest_idx ] = ctx [ digest_idx ] . clone ( ) ; // prng.digest := keccak256(digest||lastLayerCoefs). // Hash the sibling data let mut combined_data : Vec < u8 > = vec ! [ 0 32 ( last_layer_end 2 new_digest_idx ) ] ; for i in new_digest_idx ..= last_layer_end + 1 { let bytes = uint256_ops :: to_fixed_bytes ( & ctx [ i ] ) ; for j in 0 .. bytes . len ( ) { combined_data [ 32 * ( i - new_digest_idx ) + j ] = bytes [ j ] ; } } ctx [ digest_idx ] = uint256_ops :: keccak_256 ( & combined_data ) ; // prng.counter := 0. ctx [ channel_idx + 2 ] = uint256_ops :: get_uint256 ( " " ) ; // Note: proof pointer is not incremented until this point. ctx [ channel_idx ] = uint256_ops :: from_usize ( last_layer_end ) ; //Invalid field element assert ! ( bad_input 0 ) ; ctx [ map :: MM_FRI_LAST_LAYER_PTR ] = uint256_ops :: from_usize ( last_layer_idx ) ; }
Reads the last FRI layer (i.e.
Reads the last FRI layer ( i . e .
ctx
& mut Vec<Uint256>
ctx
& mut Vec<Uint256>