Repository: nexus-xyz/nexus-zkvm
File: supernova/src/circuits/nova/pcd/compression/secondary/conversion.rs (Rust)

Code before:
    // check that the moduli for the two fields match
    let ark_modulus_bytes = AF::MODULUS.to_bytes_be();
    // this is a bit of an ugly hack, but the ff PrimeField trait only provides a
    // string representation of the modulus. This might not work for all fields,
    // but it works for the grumpkin fields.
    if format!("0x{}", hex::encode(ark_modulus_bytes)) != FF::MODULUS {
        return Err(FieldConversionError::ModulusMismatch);
    }

    // ff requires N to be larger than the number of bytes in the modulus + 16,
    // so the above check should ensure this does not fail
    let mut le_bytes = [0u8; N];
    let x_le_bytes = x.into_bigint().to_bytes_le();
    // this should never fail, since we already checked that the modulus bit sizes match,
    // and `ff::FromUniformBytes`` requires N to be larger than the number of bytes in the modulus.
    assert!(x_le_bytes.len() <= N);
    le_bytes[..x_le_bytes.len()].copy_from_slice(&x_le_bytes);

    Ok(FF::from_uniform_bytes(&le_bytes))
}

/// converts a point of an arkworks short weierstrass curve to one on the corresponding halo2 curve.
/// note that the `CurveAffine` trait from `halo2curves` is for short weierstrass curves only.
/// this only works when the base field is a prime field.
/// returns an error if the curves have different equations, different base fields,
/// or different scalar fields/cofactors, or if the point is the point at infinity.
#[allow(dead_code)]
pub fn ark_to_halo2_group<AG, HG, const N: usize>(p: Affine<AG>) -> Result<HG, GroupConversionError>
where
    HG: CurveAffine,
    AG: SWCurveConfig,
    AG::BaseField: ArkPrimeField,
    HG::Base: FfPrimeField + FromUniformBytes<N>,
    HG::Scalar: FromUniformBytes<N>,
{
    let a = AG::COEFF_A;
    let b = AG::COEFF_B;

    // verify that the base fields match
    let (a_ff, b_ff) = {
        let a_ff = ark_to_ff_field::<AG::BaseField, HG::Base, N>(a)
            .map_err(|_| GroupConversionError::BaseFieldMismatch)?;
        let b_ff = ark_to_ff_field::<AG::BaseField, HG::Base, N>(b)
            .map_err(|_| GroupConversionError::BaseFieldMismatch)?;
        (a_ff, b_ff)
    };
    // verify that the curve equations match
    if a_ff != HG::a() || b_ff != HG::b() {
        return Err(GroupConversionError::EquationMismatch);
    }
    // verify that the scalar fields match

Review comment (suggestion):
Similar to https://github.com/nexus-xyz/nexus-zkvm/pull/36#discussion_r1453290126
```suggestion
/// Converts a point of an arkworks short weierstrass curve to one on the corresponding halo2 curve.
/// Note that the `CurveAffine` trait from `halo2curves` is for short weierstrass curves only.
/// This only works when the base field is a prime field.
/// Returns an error if the curves have different equations, different base fields,
/// or different scalar fields/cofactors, or if the point is the point at infinity.
```

Code after:
    // check that the moduli for the two fields match
    let ark_modulus_bytes = AF::MODULUS.to_bytes_be();
    // this is a bit of an ugly hack, but the ff PrimeField trait only provides a
    // string representation of the modulus. This might not work for all fields,
    // but it works for the grumpkin fields.
    if format!("0x{}", hex::encode(ark_modulus_bytes)) != FF::MODULUS {
        return Err(FieldConversionError::ModulusMismatch);
    }

    // ff requires N to be larger than the number of bytes in the modulus + 16,
    // so the above check should ensure this does not fail
    let mut le_bytes = [0u8; N];
    let x_le_bytes = x.into_bigint().to_bytes_le();
    // this should never fail, since we already checked that the modulus bit sizes match,
    // and `ff::FromUniformBytes`` requires N to be larger than the number of bytes in the modulus.
    assert!(x_le_bytes.len() <= N);
    le_bytes[..x_le_bytes.len()].copy_from_slice(&x_le_bytes);

    Ok(FF::from_uniform_bytes(&le_bytes))
}

/// Converts a point of an arkworks short weierstrass curve to one on the corresponding halo2 curve.
/// Note that the `CurveAffine` trait from `halo2curves` is for short weierstrass curves only.
/// This only works when the base field is a prime field.
/// Returns an error if the curves have different equations, different base fields,
/// or different scalar fields/cofactors, or if the point is the point at infinity.
#[allow(dead_code)]
pub fn ark_to_halo2_group<AG, HG, const N: usize>(p: Affine<AG>) -> Result<HG, GroupConversionError>
where
    HG: CurveAffine,
    AG: SWCurveConfig,
    AG::BaseField: ArkPrimeField,
    HG::Base: FfPrimeField + FromUniformBytes<N>,
    HG::Scalar: FromUniformBytes<N>,
{
    let a = AG::COEFF_A;
    let b = AG::COEFF_B;

    // verify that the base fields match
    let (a_ff, b_ff) = {
        let a_ff = ark_to_ff_field::<AG::BaseField, HG::Base, N>(a)
            .map_err(|_| GroupConversionError::BaseFieldMismatch)?;
        let b_ff = ark_to_ff_field::<AG::BaseField, HG::Base, N>(b)
            .map_err(|_| GroupConversionError::BaseFieldMismatch)?;
        (a_ff, b_ff)
    };
    // verify that the curve equations match
    if a_ff != HG::a() || b_ff != HG::b() {
        return Err(GroupConversionError::EquationMismatch);
    }
    // verify that the scalar fields match