Browse Source

Add typos tool to CI to automate typo detection (#76)

* Add typos to CI

* Apply typos suggestions

* missing typos
main
arnaucube 10 months ago
committed by GitHub
parent
commit
9159c5c84c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
18 changed files with 56 additions and 44 deletions
  1. +10
    -0
      .github/workflows/ci.yml
  2. +2
    -0
      .github/workflows/typos.toml
  3. +1
    -1
      folding-schemes-solidity/templates/kzg10_verifier.askama.sol
  4. +5
    -5
      folding-schemes/examples/multi_inputs.rs
  5. +2
    -2
      folding-schemes/examples/sha256.rs
  6. +1
    -1
      folding-schemes/examples/utils.rs
  7. +1
    -1
      folding-schemes/src/ccs/r1cs.rs
  8. +2
    -2
      folding-schemes/src/commitment/kzg.rs
  9. +1
    -1
      folding-schemes/src/folding/circuits/nonnative.rs
  10. +1
    -1
      folding-schemes/src/folding/hypernova/cccs.rs
  11. +3
    -3
      folding-schemes/src/folding/hypernova/lcccs.rs
  12. +2
    -2
      folding-schemes/src/folding/nova/circuits.rs
  13. +1
    -1
      folding-schemes/src/folding/nova/decider_eth.rs
  14. +2
    -2
      folding-schemes/src/folding/nova/mod.rs
  15. +14
    -14
      folding-schemes/src/folding/nova/nifs.rs
  16. +5
    -5
      folding-schemes/src/folding/protogalaxy/folding.rs
  17. +2
    -2
      folding-schemes/src/lib.rs
  18. +1
    -1
      folding-schemes/src/transcript/poseidon.rs

+ 10
- 0
.github/workflows/ci.yml

@ -102,3 +102,13 @@ jobs:
with: with:
command: clippy command: clippy
args: --all-targets --all-features -- -D warnings args: --all-targets --all-features -- -D warnings
typos:
name: Spell Check with Typos
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use typos with config file
uses: crate-ci/typos@master
with:
config: .github/workflows/typos.toml

+ 2
- 0
.github/workflows/typos.toml

@ -0,0 +1,2 @@
[default.extend-words]
groth = "groth"

+ 1
- 1
folding-schemes-solidity/templates/kzg10_verifier.askama.sol

@ -231,7 +231,7 @@ contract KZG10Verifier {
require(eval_z == 0, "checkAndCommitAuxPolys: wrong zero poly"); require(eval_z == 0, "checkAndCommitAuxPolys: wrong zero poly");
require(eval_l == y_vals[i], "checkAndCommitAuxPolys: wrong lagrange poly"); require(eval_l == y_vals[i], "checkAndCommitAuxPolys: wrong lagrange poly");
} }
// z(x) has len(x_vals) + 1 coeffs, we add to the commmitment the last coeff of z(x)
// z(x) has len(x_vals) + 1 coeffs, we add to the commitment the last coeff of z(x)
z_commit = add(z_commit, mulScalar(G1_CRS[z_coeffs.length - 1], z_coeffs[z_coeffs.length - 1])); z_commit = add(z_commit, mulScalar(G1_CRS[z_coeffs.length - 1], z_coeffs[z_coeffs.length - 1]));
return (z_commit, l_commit); return (z_commit, l_commit);

+ 5
- 5
folding-schemes/examples/multi_inputs.rs

@ -58,12 +58,12 @@ impl FCircuit for MultiInputsFCircuit {
z_i: Vec<FpVar<F>>, z_i: Vec<FpVar<F>>,
) -> Result<Vec<FpVar<F>>, SynthesisError> { ) -> Result<Vec<FpVar<F>>, SynthesisError> {
let four = FpVar::<F>::new_constant(cs.clone(), F::from(4u32))?; let four = FpVar::<F>::new_constant(cs.clone(), F::from(4u32))?;
let fourty = FpVar::<F>::new_constant(cs.clone(), F::from(40u32))?;
let forty = FpVar::<F>::new_constant(cs.clone(), F::from(40u32))?;
let onehundred = FpVar::<F>::new_constant(cs.clone(), F::from(100u32))?; let onehundred = FpVar::<F>::new_constant(cs.clone(), F::from(100u32))?;
let a = z_i[0].clone() + four.clone(); let a = z_i[0].clone() + four.clone();
let b = z_i[1].clone() + fourty.clone();
let b = z_i[1].clone() + forty.clone();
let c = z_i[2].clone() * four; let c = z_i[2].clone() * four;
let d = z_i[3].clone() * fourty;
let d = z_i[3].clone() * forty;
let e = z_i[4].clone() + onehundred; let e = z_i[4].clone() + onehundred;
Ok(vec![a, b, c, d, e]) Ok(vec![a, b, c, d, e])
@ -140,7 +140,7 @@ fn main() {
println!("Nova::prove_step {}: {:?}", i, start.elapsed()); println!("Nova::prove_step {}: {:?}", i, start.elapsed());
} }
let (running_instance, incomming_instance, cyclefold_instance) = folding_scheme.instances();
let (running_instance, incoming_instance, cyclefold_instance) = folding_scheme.instances();
println!("Run the Nova's IVC verifier"); println!("Run the Nova's IVC verifier");
NOVA::verify( NOVA::verify(
@ -149,7 +149,7 @@ fn main() {
folding_scheme.state(), // latest state folding_scheme.state(), // latest state
Fr::from(num_steps as u32), Fr::from(num_steps as u32),
running_instance, running_instance,
incomming_instance,
incoming_instance,
cyclefold_instance, cyclefold_instance,
) )
.unwrap(); .unwrap();

+ 2
- 2
folding-schemes/examples/sha256.rs

@ -125,7 +125,7 @@ fn main() {
println!("Nova::prove_step {}: {:?}", i, start.elapsed()); println!("Nova::prove_step {}: {:?}", i, start.elapsed());
} }
let (running_instance, incomming_instance, cyclefold_instance) = folding_scheme.instances();
let (running_instance, incoming_instance, cyclefold_instance) = folding_scheme.instances();
println!("Run the Nova's IVC verifier"); println!("Run the Nova's IVC verifier");
NOVA::verify( NOVA::verify(
@ -134,7 +134,7 @@ fn main() {
folding_scheme.state(), // latest state folding_scheme.state(), // latest state
Fr::from(num_steps as u32), Fr::from(num_steps as u32),
running_instance, running_instance,
incomming_instance,
incoming_instance,
cyclefold_instance, cyclefold_instance,
) )
.unwrap(); .unwrap();

+ 1
- 1
folding-schemes/examples/utils.rs

@ -13,7 +13,7 @@ use folding_schemes::transcript::poseidon::poseidon_test_config;
// This method computes the Prover & Verifier parameters for the example. // This method computes the Prover & Verifier parameters for the example.
// Warning: this method is only for testing purposes. For a real world use case those parameters // Warning: this method is only for testing purposes. For a real world use case those parameters
// should be generated carefuly (both the PoseidonConfig and the PedersenParams).
// should be generated carefully (both the PoseidonConfig and the PedersenParams).
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub(crate) fn test_nova_setup<FC: FCircuit<Fr>>( pub(crate) fn test_nova_setup<FC: FCircuit<Fr>>(
F_circuit: FC, F_circuit: FC,

+ 1
- 1
folding-schemes/src/ccs/r1cs.rs

@ -97,7 +97,7 @@ pub fn extract_r1cs(cs: &ConstraintSystem) -> R1CS {
}; };
R1CS::<F> { R1CS::<F> {
l: cs.num_instance_variables - 1, // -1 to substract the first '1'
l: cs.num_instance_variables - 1, // -1 to subtract the first '1'
A, A,
B, B,
C, C,

+ 2
- 2
folding-schemes/src/commitment/kzg.rs

@ -80,7 +80,7 @@ where
/// commit implements the CommitmentProver commit interface, adapting the implementation from /// commit implements the CommitmentProver commit interface, adapting the implementation from
/// https://github.com/arkworks-rs/poly-commit/tree/c724fa666e935bbba8db5a1421603bab542e15ab/poly-commit/src/kzg10/mod.rs#L178 /// https://github.com/arkworks-rs/poly-commit/tree/c724fa666e935bbba8db5a1421603bab542e15ab/poly-commit/src/kzg10/mod.rs#L178
/// with the main difference being the removal of the blinding factors and the no-dependancy to
/// with the main difference being the removal of the blinding factors and the no-dependency to
/// the Pairing trait. /// the Pairing trait.
fn commit( fn commit(
params: &Self::Params, params: &Self::Params,
@ -105,7 +105,7 @@ where
/// prove implements the CommitmentProver prove interface, adapting the implementation from /// prove implements the CommitmentProver prove interface, adapting the implementation from
/// https://github.com/arkworks-rs/poly-commit/tree/c724fa666e935bbba8db5a1421603bab542e15ab/poly-commit/src/kzg10/mod.rs#L307 /// https://github.com/arkworks-rs/poly-commit/tree/c724fa666e935bbba8db5a1421603bab542e15ab/poly-commit/src/kzg10/mod.rs#L307
/// with the main difference being the removal of the blinding factors and the no-dependancy to
/// with the main difference being the removal of the blinding factors and the no-dependency to
/// the Pairing trait. /// the Pairing trait.
fn prove( fn prove(
params: &Self::Params, params: &Self::Params,

+ 1
- 1
folding-schemes/src/folding/circuits/nonnative.rs

@ -10,7 +10,7 @@ use ark_relations::r1cs::{Namespace, SynthesisError};
use ark_std::{One, Zero}; use ark_std::{One, Zero};
use core::borrow::Borrow; use core::borrow::Borrow;
/// NonNativeAffineVar represents an elliptic curve point in Affine represenation in the non-native
/// NonNativeAffineVar represents an elliptic curve point in Affine representation in the non-native
/// field, over the constraint field. It is not intended to perform operations, but just to contain /// field, over the constraint field. It is not intended to perform operations, but just to contain
/// the affine coordinates in order to perform hash operations of the point. /// the affine coordinates in order to perform hash operations of the point.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

+ 1
- 1
folding-schemes/src/folding/hypernova/cccs.rs

@ -111,7 +111,7 @@ impl CCCS {
w: &Witness<C::ScalarField>, w: &Witness<C::ScalarField>,
) -> Result<(), Error> { ) -> Result<(), Error> {
// check that C is the commitment of w. Notice that this is not verifying a Pedersen // check that C is the commitment of w. Notice that this is not verifying a Pedersen
// opening, but checking that the Commmitment comes from committing to the witness.
// opening, but checking that the commitment comes from committing to the witness.
if self.C != Pedersen::commit(pedersen_params, &w.w, &w.r_w)? { if self.C != Pedersen::commit(pedersen_params, &w.w, &w.r_w)? {
return Err(Error::NotSatisfied); return Err(Error::NotSatisfied);
} }

+ 3
- 3
folding-schemes/src/folding/hypernova/lcccs.rs

@ -96,7 +96,7 @@ impl LCCCS {
w: &Witness<C::ScalarField>, w: &Witness<C::ScalarField>,
) -> Result<(), Error> { ) -> Result<(), Error> {
// check that C is the commitment of w. Notice that this is not verifying a Pedersen // check that C is the commitment of w. Notice that this is not verifying a Pedersen
// opening, but checking that the Commmitment comes from committing to the witness.
// opening, but checking that the commitment comes from committing to the witness.
if self.C != Pedersen::commit(pedersen_params, &w.w, &w.r_w)? { if self.C != Pedersen::commit(pedersen_params, &w.w, &w.r_w)? {
return Err(Error::NotSatisfied); return Err(Error::NotSatisfied);
} }
@ -133,7 +133,7 @@ pub mod tests {
let pedersen_params = Pedersen::<Projective>::new_params(&mut rng, ccs.n - ccs.l - 1); let pedersen_params = Pedersen::<Projective>::new_params(&mut rng, ccs.n - ccs.l - 1);
let (lcccs, _) = ccs.to_lcccs(&mut rng, &pedersen_params, &z).unwrap(); let (lcccs, _) = ccs.to_lcccs(&mut rng, &pedersen_params, &z).unwrap();
// with our test vector comming from R1CS, v should have length 3
// with our test vector coming from R1CS, v should have length 3
assert_eq!(lcccs.v.len(), 3); assert_eq!(lcccs.v.len(), 3);
let vec_L_j_x = lcccs.compute_Ls(&ccs, &z); let vec_L_j_x = lcccs.compute_Ls(&ccs, &z);
@ -164,7 +164,7 @@ pub mod tests {
let pedersen_params = Pedersen::<Projective>::new_params(&mut rng, ccs.n - ccs.l - 1); let pedersen_params = Pedersen::<Projective>::new_params(&mut rng, ccs.n - ccs.l - 1);
// Compute v_j with the right z // Compute v_j with the right z
let (lcccs, _) = ccs.to_lcccs(&mut rng, &pedersen_params, &z).unwrap(); let (lcccs, _) = ccs.to_lcccs(&mut rng, &pedersen_params, &z).unwrap();
// with our test vector comming from R1CS, v should have length 3
// with our test vector coming from R1CS, v should have length 3
assert_eq!(lcccs.v.len(), 3); assert_eq!(lcccs.v.len(), 3);
// Bad compute L_j(x) with the bad z // Bad compute L_j(x) with the bad z

+ 2
- 2
folding-schemes/src/folding/nova/circuits.rs

@ -445,7 +445,7 @@ where
(cf_u_i.cmE.is_zero()?).conditional_enforce_equal(&Boolean::TRUE, &is_not_basecase)?; (cf_u_i.cmE.is_zero()?).conditional_enforce_equal(&Boolean::TRUE, &is_not_basecase)?;
(cf_u_i.u.is_one()?).conditional_enforce_equal(&Boolean::TRUE, &is_not_basecase)?; (cf_u_i.u.is_one()?).conditional_enforce_equal(&Boolean::TRUE, &is_not_basecase)?;
// check the fold of all the parameteres of the CycleFold instances, where the elliptic
// check the fold of all the parameters of the CycleFold instances, where the elliptic
// curve points relations are checked natively in Curve1 circuit (this one) // curve points relations are checked natively in Curve1 circuit (this one)
let v = NIFSFullGadget::<C2, GC2>::verify( let v = NIFSFullGadget::<C2, GC2>::verify(
cf_r_bits, cf_r_bits,
@ -572,7 +572,7 @@ pub mod tests {
assert_eq!(hVar.value().unwrap(), h); assert_eq!(hVar.value().unwrap(), h);
} }
// checks that the gadget and native implementations of the challenge computation matcbh
// checks that the gadget and native implementations of the challenge computation match
#[test] #[test]
fn test_challenge_gadget() { fn test_challenge_gadget() {
let mut rng = ark_std::test_rng(); let mut rng = ark_std::test_rng();

+ 1
- 1
folding-schemes/src/folding/nova/decider_eth.rs

@ -50,7 +50,7 @@ where
<C2 as Group>::ScalarField: Absorb, <C2 as Group>::ScalarField: Absorb,
C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>, C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
for<'b> &'b GC2: GroupOpsBounds<'b, C2, GC2>, for<'b> &'b GC2: GroupOpsBounds<'b, C2, GC2>,
// constrain FS into Nova, since this is a Decider specificly for Nova
// constrain FS into Nova, since this is a Decider specifically for Nova
Nova<C1, GC1, C2, GC2, FC, CP1, CP2>: From<FS>, Nova<C1, GC1, C2, GC2, FC, CP1, CP2>: From<FS>,
{ {
type ProverParam = S::ProvingKey; type ProverParam = S::ProvingKey;

+ 2
- 2
folding-schemes/src/folding/nova/mod.rs

@ -491,11 +491,11 @@ where
z_i: Vec<C1::ScalarField>, // last state z_i: Vec<C1::ScalarField>, // last state
num_steps: C1::ScalarField, num_steps: C1::ScalarField,
running_instance: Self::CommittedInstanceWithWitness, running_instance: Self::CommittedInstanceWithWitness,
incomming_instance: Self::CommittedInstanceWithWitness,
incoming_instance: Self::CommittedInstanceWithWitness,
cyclefold_instance: Self::CFCommittedInstanceWithWitness, cyclefold_instance: Self::CFCommittedInstanceWithWitness,
) -> Result<(), Error> { ) -> Result<(), Error> {
let (U_i, W_i) = running_instance; let (U_i, W_i) = running_instance;
let (u_i, w_i) = incomming_instance;
let (u_i, w_i) = incoming_instance;
let (cf_U_i, cf_W_i) = cyclefold_instance; let (cf_U_i, cf_W_i) = cyclefold_instance;
if u_i.x.len() != 1 || U_i.x.len() != 1 { if u_i.x.len() != 1 || U_i.x.len() != 1 {

+ 14
- 14
folding-schemes/src/folding/nova/nifs.rs

@ -143,7 +143,7 @@ where
// use r_T=1 since we don't need hiding property for cm(T) // use r_T=1 since we don't need hiding property for cm(T)
let w3 = NIFS::<C, CP>::fold_witness(r, w1, w2, T, C::ScalarField::one())?; let w3 = NIFS::<C, CP>::fold_witness(r, w1, w2, T, C::ScalarField::one())?;
// fold committed instancs
// fold committed instances
let ci3 = NIFS::<C, CP>::fold_committed_instance(r, ci1, ci2, &cmT); let ci3 = NIFS::<C, CP>::fold_committed_instance(r, ci1, ci2, &cmT);
Ok((w3, ci3)) Ok((w3, ci3))
@ -161,7 +161,7 @@ where
NIFS::<C, CP>::fold_committed_instance(r, ci1, ci2, cmT) NIFS::<C, CP>::fold_committed_instance(r, ci1, ci2, cmT)
} }
/// Verify commited folded instance (ci) relations. Notice that this method does not open the
/// Verify committed folded instance (ci) relations. Notice that this method does not open the
/// commitments, but just checks that the given committed instances (ci1, ci2) when folded /// commitments, but just checks that the given committed instances (ci1, ci2) when folded
/// result in the folded committed instance (ci3) values. /// result in the folded committed instance (ci3) values.
pub fn verify_folded_instance( pub fn verify_folded_instance(
@ -426,16 +426,16 @@ pub mod tests {
let num_iters = 10; let num_iters = 10;
for i in 0..num_iters { for i in 0..num_iters {
// prepare the incomming instance
let incomming_instance_z = get_test_z(i + 4);
let (w, x) = r1cs.split_z(&incomming_instance_z);
let incomming_instance_w = Witness::<Projective>::new(w.clone(), r1cs.A.n_rows);
let incomming_committed_instance = incomming_instance_w
// prepare the incoming instance
let incoming_instance_z = get_test_z(i + 4);
let (w, x) = r1cs.split_z(&incoming_instance_z);
let incoming_instance_w = Witness::<Projective>::new(w.clone(), r1cs.A.n_rows);
let incoming_committed_instance = incoming_instance_w
.commit::<Pedersen<Projective>>(&pedersen_params, x) .commit::<Pedersen<Projective>>(&pedersen_params, x)
.unwrap(); .unwrap();
r1cs.check_relaxed_instance_relation( r1cs.check_relaxed_instance_relation(
&incomming_instance_w,
&incomming_committed_instance,
&incoming_instance_w,
&incoming_committed_instance,
) )
.unwrap(); .unwrap();
@ -447,16 +447,16 @@ pub mod tests {
&r1cs, &r1cs,
&running_instance_w, &running_instance_w,
&running_committed_instance, &running_committed_instance,
&incomming_instance_w,
&incomming_committed_instance,
&incoming_instance_w,
&incoming_committed_instance,
) )
.unwrap(); .unwrap();
let (folded_w, _) = NIFS::<Projective, Pedersen<Projective>>::fold_instances( let (folded_w, _) = NIFS::<Projective, Pedersen<Projective>>::fold_instances(
r, r,
&running_instance_w, &running_instance_w,
&running_committed_instance, &running_committed_instance,
&incomming_instance_w,
&incomming_committed_instance,
&incoming_instance_w,
&incoming_committed_instance,
&T, &T,
cmT, cmT,
) )
@ -466,7 +466,7 @@ pub mod tests {
let folded_committed_instance = NIFS::<Projective, Pedersen<Projective>>::verify( let folded_committed_instance = NIFS::<Projective, Pedersen<Projective>>::verify(
r, r,
&running_committed_instance, &running_committed_instance,
&incomming_committed_instance,
&incoming_committed_instance,
&cmT, &cmT,
); );

+ 5
- 5
folding-schemes/src/folding/protogalaxy/folding.rs

@ -40,7 +40,7 @@ where
// running instance // running instance
instance: &CommittedInstance<C>, instance: &CommittedInstance<C>,
w: &Witness<C::ScalarField>, w: &Witness<C::ScalarField>,
// incomming instances
// incoming instances
vec_instances: &[CommittedInstance<C>], vec_instances: &[CommittedInstance<C>],
vec_w: &[Witness<C::ScalarField>], vec_w: &[Witness<C::ScalarField>],
) -> Result< ) -> Result<
@ -226,7 +226,7 @@ where
r1cs: &R1CS<C::ScalarField>, r1cs: &R1CS<C::ScalarField>,
// running instance // running instance
instance: &CommittedInstance<C>, instance: &CommittedInstance<C>,
// incomming instances
// incoming instances
vec_instances: &[CommittedInstance<C>], vec_instances: &[CommittedInstance<C>],
// polys from P // polys from P
F_coeffs: Vec<C::ScalarField>, F_coeffs: Vec<C::ScalarField>,
@ -440,7 +440,7 @@ mod tests {
assert!(!is_zero_vec(&f_w)); assert!(!is_zero_vec(&f_w));
} }
// k represents the number of instances to be fold, appart from the running instance
// k represents the number of instances to be fold, apart from the running instance
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
fn prepare_inputs( fn prepare_inputs(
k: usize, k: usize,
@ -522,7 +522,7 @@ mod tests {
) )
.unwrap(); .unwrap();
// veriier
// verifier
let folded_instance_v = Folding::<Projective>::verify( let folded_instance_v = Folding::<Projective>::verify(
&mut transcript_v, &mut transcript_v,
&r1cs, &r1cs,
@ -572,7 +572,7 @@ mod tests {
) )
.unwrap(); .unwrap();
// veriier
// verifier
let folded_instance_v = Folding::<Projective>::verify( let folded_instance_v = Folding::<Projective>::verify(
&mut transcript_v, &mut transcript_v,
&r1cs, &r1cs,

+ 2
- 2
folding-schemes/src/lib.rs

@ -42,7 +42,7 @@ pub enum Error {
NotExpectedLength(usize, usize), NotExpectedLength(usize, usize),
#[error("Can not be empty")] #[error("Can not be empty")]
Empty, Empty,
#[error("Pedersen parameters length is not suficient (generators.len={0} < vector.len={1} unsatisfied)")]
#[error("Pedersen parameters length is not sufficient (generators.len={0} < vector.len={1} unsatisfied)")]
PedersenParamsLen(usize, usize), PedersenParamsLen(usize, usize),
#[error("Commitment verification failed")] #[error("Commitment verification failed")]
CommitmentVerificationFail, CommitmentVerificationFail,
@ -116,7 +116,7 @@ where
// number of steps between the initial state and the last state // number of steps between the initial state and the last state
num_steps: C1::ScalarField, num_steps: C1::ScalarField,
running_instance: Self::CommittedInstanceWithWitness, running_instance: Self::CommittedInstanceWithWitness,
incomming_instance: Self::CommittedInstanceWithWitness,
incoming_instance: Self::CommittedInstanceWithWitness,
cyclefold_instance: Self::CFCommittedInstanceWithWitness, cyclefold_instance: Self::CFCommittedInstanceWithWitness,
) -> Result<(), Error>; ) -> Result<(), Error>;
} }

+ 1
- 1
folding-schemes/src/transcript/poseidon.rs

@ -57,7 +57,7 @@ where
} }
} }
// Returns the point coordinates in Fr, so it can be absrobed by the transcript. It does not work
// Returns the point coordinates in Fr, so it can be absorbed by the transcript. It does not work
// over bytes in order to have a logic that can be reproduced in-circuit. // over bytes in order to have a logic that can be reproduced in-circuit.
fn prepare_point<C: CurveGroup>(p: &C) -> Result<Vec<C::ScalarField>, Error> { fn prepare_point<C: CurveGroup>(p: &C) -> Result<Vec<C::ScalarField>, Error> {
let affine = p.into_affine(); let affine = p.into_affine();

Loading…
Cancel
Save