fn quarkslab_scalar_overflow_does_not_occur()

in src/scalar.rs [1413:1458]


    fn quarkslab_scalar_overflow_does_not_occur() {
        // Check that manually-constructing large Scalars with
        // from_bits cannot produce incorrect results.
        //
        // The from_bits function is required to implement X/Ed25519,
        // while all other methods of constructing a Scalar produce
        // reduced Scalars.  However, this "invariant loophole" allows
        // constructing large scalars which are not reduced mod l.
        //
        // This issue was discovered independently by both Jack
        // "str4d" Grigg (issue #238), who noted that reduction was
        // not performed on addition, and Laurent Grémy & Nicolas
        // Surbayrole of Quarkslab, who noted that it was possible to
        // cause an overflow and compute incorrect results.
        //
        // This test is adapted from the one suggested by Quarkslab.

        let large_bytes = [
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
        ];

        let a = Scalar::from_bytes_mod_order(large_bytes);
        let b = Scalar::from_bits(large_bytes);

        assert_eq!(a, b.reduce());

        let a_3 = a + a + a;
        let b_3 = b + b + b;

        assert_eq!(a_3, b_3);

        let neg_a = -a;
        let neg_b = -b;

        assert_eq!(neg_a, neg_b);

        let minus_a_3 = Scalar::zero() - a - a - a;
        let minus_b_3 = Scalar::zero() - b - b - b;

        assert_eq!(minus_a_3, minus_b_3);
        assert_eq!(minus_a_3, -a_3);
        assert_eq!(minus_b_3, -b_3);
    }