decaf377/ark_curve/
on_curve.rs

1use ark_ec::{
2    models::{twisted_edwards::Projective, twisted_edwards::TECurveConfig},
3    Group,
4};
5use ark_ff::{BigInteger, Field, PrimeField, Zero};
6use ark_serialize::CanonicalSerialize;
7
8use crate::ark_curve::constants;
9
10pub trait OnCurve {
11    fn is_on_curve(&self) -> bool;
12}
13
14#[cfg(feature = "arkworks")]
15impl<P: TECurveConfig> OnCurve for Projective<P> {
16    #[allow(non_snake_case)]
17    fn is_on_curve(&self) -> bool {
18        let XX = self.x.square();
19        let YY = self.y.square();
20        let ZZ = self.z.square();
21        let TT = self.t.square();
22
23        let on_curve = (YY + P::COEFF_A * XX) == (ZZ + P::COEFF_D * TT);
24        let on_segre_embedding = self.t * self.z == self.x * self.y;
25        let z_non_zero = self.z != P::BaseField::zero();
26        let point_order_2r = {
27            let mut r_bytes = [0u8; 32];
28            (*constants::R)
29                .serialize_compressed(&mut r_bytes[..])
30                .expect("serialization into array should be infallible");
31            let r = P::ScalarField::from_le_bytes_mod_order(&r_bytes);
32            let mut two_r_bigint = r.into_bigint();
33            two_r_bigint.mul2();
34            self.mul_bigint(two_r_bigint) == Projective::zero()
35        };
36
37        on_curve && on_segre_embedding && z_non_zero && point_order_2r
38    }
39}