decaf377/ark_curve/
on_curve.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use ark_ec::{
    models::{twisted_edwards::Projective, twisted_edwards::TECurveConfig},
    Group,
};
use ark_ff::{BigInteger, Field, PrimeField, Zero};
use ark_serialize::CanonicalSerialize;

use crate::ark_curve::constants;

pub trait OnCurve {
    fn is_on_curve(&self) -> bool;
}

#[cfg(feature = "arkworks")]
impl<P: TECurveConfig> OnCurve for Projective<P> {
    #[allow(non_snake_case)]
    fn is_on_curve(&self) -> bool {
        let XX = self.x.square();
        let YY = self.y.square();
        let ZZ = self.z.square();
        let TT = self.t.square();

        let on_curve = (YY + P::COEFF_A * XX) == (ZZ + P::COEFF_D * TT);
        let on_segre_embedding = self.t * self.z == self.x * self.y;
        let z_non_zero = self.z != P::BaseField::zero();
        let point_order_2r = {
            let mut r_bytes = [0u8; 32];
            (*constants::R)
                .serialize_compressed(&mut r_bytes[..])
                .expect("serialization into array should be infallible");
            let r = P::ScalarField::from_le_bytes_mod_order(&r_bytes);
            let mut two_r_bigint = r.into_bigint();
            two_r_bigint.mul2();
            self.mul_bigint(two_r_bigint) == Projective::zero()
        };

        on_curve && on_segre_embedding && z_non_zero && point_order_2r
    }
}