fn pre_reduced_scalar()

in src/main.rs [605:666]


fn pre_reduced_scalar() -> TestVector {
    let mut rng = new_rng();

    // Pick a random scalar
    let mut scalar_bytes = [0u8; 32];
    rng.fill_bytes(&mut scalar_bytes);
    let a = Scalar::from_bytes_mod_order(scalar_bytes);
    debug_assert!(a.is_canonical());
    debug_assert!(a != Scalar::zero());
    // Pick a random nonce
    let nonce_bytes = [0u8; 32];
    rng.fill_bytes(&mut scalar_bytes);

    // generate the r of a "normal" signature
    let prelim_pub_key = a * ED25519_BASEPOINT_POINT;

    // Pick a torsion point
    let small_idx: usize = rng.next_u64() as usize;
    let small_pt = pick_small_nonzero_point(small_idx + 1);
    let pub_key = prelim_pub_key + small_pt;

    let mut message = [0u8; 32];
    rng.fill_bytes(&mut message);
    let mut h = Sha512::new();
    h.update(&nonce_bytes);
    h.update(&message);

    let mut output = [0u8; 64];
    output.copy_from_slice(h.finalize().as_slice());
    let r_scalar = curve25519_dalek::scalar::Scalar::from_bytes_mod_order_wide(&output);
    let r = r_scalar * ED25519_BASEPOINT_POINT;

    // grind a k so that 8*k gets reduced to a number NOT multiple of eight,
    // and add a small order component to the public key.
    while multiple_of_eight_le(eight() * compute_hram(&message, &pub_key, &r)) {
        rng.fill_bytes(&mut message);
    }

    let s = r_scalar + compute_hram(&message, &pub_key, &r) * a;

    // that's because we do cofactored verification without pre-reducing scalars
    debug_assert!(verify_cofactored(&message, &pub_key, &(r, s)).is_ok());

    // pre-reducing is a mistake
    debug_assert!(verify_pre_reduced_cofactored(&message, &pub_key, &(r, s)).is_err());

    // as expected
    debug_assert!(verify_cofactorless(&message, &pub_key, &(r, s)).is_err());
    debug!(
        "S > 0, mixed A, large order R\n\
         passes cofactored, fails pre-reducing cofactored, fails cofactorless\n\
         \"message\": \"{}\", \"pub_key\": \"{}\", \"signature\": \"{}\"",
        hex::encode(&message),
        hex::encode(&pub_key.compress().as_bytes()),
        hex::encode(&serialize_signature(&r, &s))
    );
    TestVector {
        message,
        pub_key: pub_key.compress().to_bytes(),
        signature: serialize_signature(&r, &s),
    }
}