> For the complete documentation index, see [llms.txt](https://thias-organization.gitbook.io/p256-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://thias-organization.gitbook.io/p256-documentation/risc-zero-p256-accelerator/affine-and-projective-points.md).

# Affine and Projective Points

In the k256 curve `arithmetic.rs`, they defined their own `ProjectivePoint` and `AffinePoint`. Whereas in the original p256 curve, a general `primeOrder::ProjectivePoint` and `primeOrder::AffinePoint`.&#x20;

We want to be able to modify the arithemetic operations in `ProjectivePoints` like [how RISC Zero did for k256](/p256-documentation/risc-zero-k256-accelerator/affine-and-projective-points.md). More specifically we would like to use `mul_single` that we defined in `FieldElement` to replace some of the repeated additions.&#x20;

This was not possible initially as the point arithmetic operations in `primeOrder::ProjectivePoints` were defined for generic curves which may not have the `mul_single` operation defined for their `FieldElement`. Hence, we had to define out own`ProjectivePoint` and `AffinePoint` like what k256 has.

To do so, we:

1. Create new files `projective.rs` and `affine.rs` with `ProjectivePoint` and `AffinePoint` defined specifically for p256 curve respectively
2. Copy over all the functions defined and both `primeOrder::ProjectivePoint` and `primeOrder::AffinePoint` into the new definition and removing all references to generic type `<C>`
3. Perform optimisation on `add`, `add_mixed` and `double` for zkVM architecture

## Optimisations

`add`, `add_mixed` and `double` implemented Algorithm 4, 5 and 6 respectively from [\[Renes-Costello-Batina, 2015\]](https://eprint.iacr.org/2015/1060.pdf) which are specific for elliptic curves with the constant $$a = -3$$.

The optimisations were similar to the ones highlighted in [Complete Addition](/p256-documentation/risc-zero-k256-accelerator/affine-and-projective-points.md#complete-projective-addition).

```rust
/// Returns `self + other`.
/// Implements complete addition for curves with `a = -3`
///
/// Implements the complete addition formula from [Renes-Costello-Batina 2015]
/// (Algorithm 4). The comments after each line indicate which algorithm steps
/// are being performed.
///
/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
pub fn add(&self, other: &ProjectivePoint) -> ProjectivePoint {
    if cfg!(all(target_os = "zkvm", target_arch = "riscv32")) {
        let bzz_part = xz_pairs - zz.mul(CURVE_EQUATION_B); // 19, 20
        let bzz3_part = bzz_part.mul_single(3); // 21, 22
        //...
    }
    // else if it is not zkVM
    let bzz_part = xz_pairs - (CURVE_EQUATION_B * zz); // 19, 20
    let bzz3_part = bzz_part.double() + bzz_part; // 21, 22
    //...
}
```
