curveforge 0.3.0

Optimised, secure, and generalised algorithms for elliptic curve arithmetic
Documentation
use crate::models::montgomery::*;
use crate::prelude::*;

elliptic_curve! {
    [attributes]
    name = Curve448
    model = Montgomery

    field_size = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
    group_size = 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3

    generator = (0x05, 0x01)
    identity = (0x1, 0x0)

    [constants]
    a = 0x262a6
    b = 0x01

    [properties]
    serialized_bytes = 56
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn serialize_deserialize_generator() {
        let g = <Curve448 as EllipticCurve>::Point::generator();

        let r1 = <<Curve448 as EllipticCurve>::Point as DeserializePoint>::deserialize(g.serialize());

        assert!(g.equal(r1.clone()).unwrap_u8() != 0, "Expected \n{:#?}, but received \n{:#?}", g, r1)
    }

    #[test]
    fn serialize_deserialize() {
        let g = <Curve448 as EllipticCurve>::Point::generator();
        let s = <Curve448 as EllipticCurve>::Scalar::random(rand::rng());

        let r0 = g.scalar_mul(s);
        let r1 = <<Curve448 as EllipticCurve>::Point as DeserializePoint>::deserialize(r0.serialize());

        assert!(r0.clone().equal(r1.clone()).unwrap_u8() != 0, "Expected \n{:#?}, but received \n{:#?}", r0, r1)
    }

    #[test]
    fn small_multiplication() {
        let g = <Curve448 as EllipticCurve>::Point::generator();

        let mut p0 = g.clone();
        let mut s = DynamicElement::ONE;
        for i in 0usize..32usize {
            let p1 = g.clone().scalar_mul(s);

            let r0 = p0.clone().serialize();
            let r1 = p1.serialize();

            assert!(
                r0 == r1,
                "Small Randomized Multiplication s=2^{} error: expected {:?}, but received {:?}",
                i,
                &r0,
                &r1
            );

            s = s.dbl();
            p0 = p0.dbl();
        }
    }

    #[test]
    fn multiplication() {
        let g = <Curve448 as EllipticCurve>::Point::generator();

        for i in 1..32 {
            let s0 = <Curve448 as EllipticCurve>::Scalar::random(rand::rng());
            let s1 = <Curve448 as EllipticCurve>::Scalar::random(rand::rng());
            let s2 = s0 * s1;

            let p0 = g.clone().scalar_mul(s0);
            let p1 = p0.clone().scalar_mul(s1);
            let p2 = g.clone().scalar_mul(s2);

            let r1 = p1.serialize();
            let r2 = p2.serialize();

            assert!(r1 == r2, "Randomized Multiplication {} error: expected {:#?}, but received {:#?}", i, &p1, &p2);
        }
    }

    #[test]
    fn test_negation() {
        let g = <Curve448 as EllipticCurve>::Point::generator();

        for _ in 1..32 {
            let s = <Curve448 as EllipticCurve>::Scalar::random(rand::rng());
            let p = g.clone().scalar_mul(s);

            assert!(bool::from(p.clone().neg().neg().equal(p)), "Could not double negate on {s:?}");
        }
    }

    #[test]
    fn test_one_minus_one() {
        let one: DynamicElement<<Curve448 as EllipticCurve>::Scalar> = DynamicElement::ONE;
        let minus_one = -one;
        let zero = DynamicElement::ZERO;

        assert_eq!(zero, one + minus_one);
        assert_eq!(zero, one - one);
        assert_eq!(zero, one + -one);

        let one: DynamicElement<<Curve448 as EllipticCurve>::Base> = DynamicElement::ONE;
        let minus_one = -one;
        let zero = DynamicElement::ZERO;

        assert_eq!(zero, one + minus_one);
        assert_eq!(zero, one - one);
        assert_eq!(zero, one + -one);
    }
}