Skip to main content

hotshot_contract_adapter/
points.rs

1//! Conversions between arkworks curve points and their Solidity representations.
2
3use alloy::primitives::U256;
4use ark_ec::{
5    AffineRepr,
6    short_weierstrass::{Affine, SWCurveConfig},
7    twisted_edwards::{self, TECurveConfig},
8};
9use ark_ff::{Fp2, Fp2Config, PrimeField};
10
11use crate::{
12    field_to_u256,
13    sol_types::{EdOnBN254PointSol, G1PointSol, G2PointSol},
14    u256_to_field,
15};
16
17impl<P: SWCurveConfig> From<Affine<P>> for G1PointSol
18where
19    P::BaseField: PrimeField,
20{
21    fn from(p: Affine<P>) -> Self {
22        if p.is_zero() {
23            // this convention is from the BN precompile
24            Self {
25                x: U256::from(0),
26                y: U256::from(0),
27            }
28        } else {
29            Self {
30                x: field_to_u256::<P::BaseField>(p.x().unwrap()),
31                y: field_to_u256::<P::BaseField>(p.y().unwrap()),
32            }
33        }
34    }
35}
36
37impl<P: SWCurveConfig> From<G1PointSol> for Affine<P>
38where
39    P::BaseField: PrimeField,
40{
41    fn from(p: G1PointSol) -> Self {
42        if p == G1PointSol::default() {
43            Self::default()
44        } else {
45            Self::new_unchecked(
46                u256_to_field::<P::BaseField>(p.x),
47                u256_to_field::<P::BaseField>(p.y),
48            )
49        }
50    }
51}
52
53impl<P: SWCurveConfig<BaseField = Fp2<C>>, C> From<G2PointSol> for Affine<P>
54where
55    C: Fp2Config,
56{
57    fn from(p: G2PointSol) -> Self {
58        Self::new_unchecked(
59            Fp2::new(u256_to_field(p.x0), u256_to_field(p.x1)),
60            Fp2::new(u256_to_field(p.y0), u256_to_field(p.y1)),
61        )
62    }
63}
64
65impl<P: SWCurveConfig<BaseField = Fp2<C>>, C> From<Affine<P>> for G2PointSol
66where
67    C: Fp2Config,
68{
69    fn from(p: Affine<P>) -> Self {
70        Self {
71            x0: field_to_u256(p.x().unwrap().c0),
72            x1: field_to_u256(p.x().unwrap().c1),
73            y0: field_to_u256(p.y().unwrap().c0),
74            y1: field_to_u256(p.y().unwrap().c1),
75        }
76    }
77}
78
79impl<P: TECurveConfig> From<twisted_edwards::Affine<P>> for EdOnBN254PointSol
80where
81    P::BaseField: PrimeField,
82{
83    fn from(p: twisted_edwards::Affine<P>) -> Self {
84        Self {
85            x: field_to_u256::<P::BaseField>(p.x().unwrap()),
86            y: field_to_u256::<P::BaseField>(p.y().unwrap()),
87        }
88    }
89}
90
91impl<P: TECurveConfig> From<EdOnBN254PointSol> for twisted_edwards::Affine<P>
92where
93    P::BaseField: PrimeField,
94{
95    fn from(p: EdOnBN254PointSol) -> Self {
96        Self::new_unchecked(
97            u256_to_field::<P::BaseField>(p.x),
98            u256_to_field::<P::BaseField>(p.y),
99        )
100    }
101}