Simply describe of the 3 issues:
- 3.6: Usage of point types with malformed values
- Some malformed elements of the types ark_bn254::G1Affine and ark_bn254::G2Affine are constructed. For instance,
G1Affine::push( ark_bn254::G1Affine::new_unchecked(ark_bn254::Fq::ZERO,
ark_bn254::Fq::ZERO))}
Fix proposal: we suppose to use G1/G2Affine::new() to create all the corresponding elements.
- Operations on malformed values
In wrap_chunk_point_ops_and_multiply_line_evals_step_1,
q4 = Some(ark_bn254::G2Affine::new_unchecked(
ark_bn254::Fq2::new(q4xc0.into(), q4xc1.into()),
ark_bn254::Fq2::new(q4yc0.into(), q4yc1.into()),
));
Fix proposal: check if q4 is on twisted curve E', y² = x³ + 3/(u+9).
- Incorrect handling of the point at infinity in Rust code: for example, as_hints_g1type_g1data.
Fix proposal: we suppose to check if the ark_bn254::G1Affine/ark_bn254::G2Affine are points on the curve. A cheap version is to check before pushing into script stack, another expensive fix is checking in the script. But I prefer checking before pushing into stack.
- Incorrect translation of the point at infinity between ark_bn254 and stack values
On the stack, the point infinity is represented by the pair (0,0) in the respective coordinate types. When translating between stack values and ark_bn254 point values, the infinity case needs to be
checked, i.e. bn254/g1.rs:push(), bn254/g1.rs:read_from_stack.
Fix proposal: add infinity point check when push into or read from between host and stack environment.
- Usage of G1Affine with incorrect coordinate system
For example:
// taps_ext_miller.rs:chunk_precompute_p
let pdy = py.inverse().unwrap();
let pdx = -px * pdy;
ark_bn254::G1Affine::new_unchecked(pdx, pdy)
Fix proposal:
let pdy = py.inverse().unwrap(); // m = 1 / y
let pdx = -px * pdy; // n = -x / y
// Convert back to (x, y) on the original curve:
// y = 1 / m = 1 / pdy
// x = -n / m = -pdx / pdy
let y = pdy.inverse().unwrap();
let x = -pdx * y;
// Sanity check: ensure (x, y) is actually on BN254: y^2 = x^3 + 3
assert_eq!(y.square(), x.square() * x + Fq::from(3u64));
// Now it is safe to construct G1Affine
G1Affine::new_unchecked(x, y)
- 3.12. Incomplete handling of G1 point addition
Fix proposal: We also need to handle T==Q or -Q for function bn254::g1::G1Affine::hinted_check_add. The cheap fix is to add an assertion that T should not equals Q or -Q in this function, which should not happens actually. Another one is to handle T == Q or -Q properly in the script. Will provide 2 implementations, and allow the caller to decide which one should be used.
- 3.24. Improper detection of invalid input to E' addition
Fix proposal: handle as same as 3.12.
Notes
Any point validity checking in the script may lead to the chunker refactor.
Simply describe of the 3 issues:
Fix proposal: we suppose to use G1/G2Affine::new() to create all the corresponding elements.
q4 = Some(ark_bn254::G2Affine::new_unchecked( ark_bn254::Fq2::new(q4xc0.into(), q4xc1.into()), ark_bn254::Fq2::new(q4yc0.into(), q4yc1.into()), ));Fix proposal: check if q4 is on twisted curve E', y² = x³ + 3/(u+9).
Fix proposal: we suppose to check if the ark_bn254::G1Affine/ark_bn254::G2Affine are points on the curve. A cheap version is to check before pushing into script stack, another expensive fix is checking in the script. But I prefer checking before pushing into stack.
On the stack, the point infinity is represented by the pair (0,0) in the respective coordinate types. When translating between stack values and ark_bn254 point values, the infinity case needs to be
checked, i.e. bn254/g1.rs:push(), bn254/g1.rs:read_from_stack.
Fix proposal: add infinity point check when push into or read from between host and stack environment.
For example:
Fix proposal:
let pdy = py.inverse().unwrap(); // m = 1 / y let pdx = -px * pdy; // n = -x / y // Convert back to (x, y) on the original curve: // y = 1 / m = 1 / pdy // x = -n / m = -pdx / pdy let y = pdy.inverse().unwrap(); let x = -pdx * y; // Sanity check: ensure (x, y) is actually on BN254: y^2 = x^3 + 3 assert_eq!(y.square(), x.square() * x + Fq::from(3u64)); // Now it is safe to construct G1Affine G1Affine::new_unchecked(x, y)Fix proposal: We also need to handle T==Q or -Q for function bn254::g1::G1Affine::hinted_check_add. The cheap fix is to add an assertion that T should not equals Q or -Q in this function, which should not happens actually. Another one is to handle T == Q or -Q properly in the script. Will provide 2 implementations, and allow the caller to decide which one should be used.
Fix proposal: handle as same as 3.12.
Notes
Any point validity checking in the script may lead to the chunker refactor.