diff --git a/docs/docs/contributor-guide.md b/docs/docs/contributor-guide.md index ffd82cd9..fbbf8b56 100644 --- a/docs/docs/contributor-guide.md +++ b/docs/docs/contributor-guide.md @@ -1,6 +1,6 @@ # Contributor's Guide -We welcome all contributions with open arms. At Ingonyama we take a village approach, believing it takes many hands and minds to build a ecosystem. +We welcome all contributions with open arms. At Ingonyama we take a village approach, believing it takes many hands and minds to build an ecosystem. ## Contributing to ICICLE @@ -14,9 +14,9 @@ We welcome all contributions with open arms. At Ingonyama we take a village appr When opening a [pull request](https://github.com/ingonyama-zk/icicle/pulls) please keep the following in mind. - `Clear Purpose` - The pull request should solve a single issue and be clean of any unrelated changes. -- `Clear description` - If the pull request is for a new feature describe what you built, why you added it and how its best that we test it. For bug fixes please describe the issue and the solution. +- `Clear description` - If the pull request is for a new feature describe what you built, why you added it and how it's best that we test it. For bug fixes please describe the issue and the solution. - `Consistent style` - Rust and Golang code should be linted by the official linters (golang fmt and rust fmt) and maintain a proper style. For CUDA and C++ code we use [`clang-format`](https://github.com/ingonyama-zk/icicle/blob/main/.clang-format), [here](https://github.com/ingonyama-zk/icicle/blob/605c25f9d22135c54ac49683b710fe2ce06e2300/.github/workflows/main-format.yml#L46) you can see how we run it. -- `Minimal Tests` - please add test which cover basic usage of your changes . +- `Minimal Tests` - please add test which cover basic usage of your changes. ## Questions? diff --git a/docs/docs/icicle/golang-bindings/ecntt.md b/docs/docs/icicle/golang-bindings/ecntt.md index 3947995e..31b94671 100644 --- a/docs/docs/icicle/golang-bindings/ecntt.md +++ b/docs/docs/icicle/golang-bindings/ecntt.md @@ -47,7 +47,7 @@ type NTTConfig[T any] struct { - **`areInputsOnDevice`**: Indicates if input scalars are located on the device. - **`areOutputsOnDevice`**: Indicates if results are stored on the device. - **`IsAsync`**: Controls whether the NTT operation runs asynchronously. -- **`NttAlgorithm`**: Explicitly select the NTT algorithm. ECNTT supports running on `Radix2` algoruithm. +- **`NttAlgorithm`**: Explicitly select the NTT algorithm. ECNTT supports running on `Radix2` algorithm. ### Default Configuration diff --git a/docs/docs/icicle/golang-bindings/msm.md b/docs/docs/icicle/golang-bindings/msm.md index 72710c55..1780950b 100644 --- a/docs/docs/icicle/golang-bindings/msm.md +++ b/docs/docs/icicle/golang-bindings/msm.md @@ -139,7 +139,7 @@ cfg.Ctx.IsBigTriangle = true Toggling between MSM modes occurs automatically based on the number of results you are expecting from the `MSM` function. -The number of results is interpreted from the size of `var out core.DeviceSlice`. Thus its important when allocating memory for `var out core.DeviceSlice` to make sure that you are allocating ` X `. +The number of results is interpreted from the size of `var out core.DeviceSlice`. Thus it's important when allocating memory for `var out core.DeviceSlice` to make sure that you are allocating ` X `. ```go ... @@ -168,7 +168,7 @@ import ( ) ``` -This package include `G2Projective` and `G2Affine` points as well as a `G2Msm` method. +This package includes `G2Projective` and `G2Affine` points as well as a `G2Msm` method. ```go package main diff --git a/docs/docs/icicle/polynomials/overview.md b/docs/docs/icicle/polynomials/overview.md index 06058ffe..25ba9dee 100644 --- a/docs/docs/icicle/polynomials/overview.md +++ b/docs/docs/icicle/polynomials/overview.md @@ -171,7 +171,7 @@ Polynomial& add_monomial_inplace(Coeff monomial_coeff, uint64_t monomial = 0); Polynomial& sub_monomial_inplace(Coeff monomial_coeff, uint64_t monomial = 0); ``` -The ability to add or subtract monomials directly and in-place is an efficient way to manipualte polynomials. +The ability to add or subtract monomials directly and in-place is an efficient way to manipulate polynomials. Example: diff --git a/docs/docs/icicle/primitives/msm.md b/docs/docs/icicle/primitives/msm.md index 7cb4a0ab..7b12f96e 100644 --- a/docs/docs/icicle/primitives/msm.md +++ b/docs/docs/icicle/primitives/msm.md @@ -1,6 +1,6 @@ # MSM - Multi scalar multiplication -MSM stands for Multi scalar multiplication, its defined as: +MSM stands for Multi scalar multiplication, it's defined as: M @@ -43,7 +43,7 @@ $a_0, \ldots, a_n$ - Scalars $MSM(a, G) \in G$ - a single EC (elliptic curve) point -In words, MSM is the sum of scalar and EC point multiplications. We can see from this definition that the core operations occurring are Modular Multiplication and Elliptic curve point addition. Its obvious that multiplication can be computed in parallel and then the products summed, making MSM inherently parallelizable. +In words, MSM is the sum of scalar and EC point multiplications. We can see from this definition that the core operations occurring are Modular Multiplication and Elliptic curve point addition. It's obvious that multiplication can be computed in parallel and then the products summed, making MSM inherently parallelizable. Accelerating MSM is crucial to a ZK protocol's performance due to the [large percent of run time](https://hackmd.io/@0xMonia/SkQ6-oRz3#Hardware-acceleration-in-action) they take when generating proofs. @@ -131,7 +131,7 @@ Large buckets exist in two cases: 2. When `c` does not divide the scalar bit-size. `large_bucket_factor` that is equal to 10 yields good results for most cases, but it's best to fine tune this parameter per `c` and per scalar distribution. -The two most important parameters for performance are `c` and the `precompute_factor`. They affect the number of EC additions as well as the memory size. When the points are not known in advance we cannot use precomputation. In this case the best `c` value is usually around $log_2(msmSize) - 4$. However, in most protocols the points are known in advanced and precomputation can be used unless limited by memory. Usually it's best to use maximum precomputation (such that we end up with only a single bucket module) combined we a `c` value around $log_2(msmSize) - 1$. +The two most important parameters for performance are `c` and the `precompute_factor`. They affect the number of EC additions as well as the memory size. When the points are not known in advance we cannot use precomputation. In this case the best `c` value is usually around $log_2(msmSize) - 4$. However, in most protocols the points are known in advance and precomputation can be used unless limited by memory. Usually it's best to use maximum precomputation (such that we end up with only a single bucket module) combined with a `c` value around $log_2(msmSize) - 1$. ## Memory usage estimation diff --git a/docs/docs/icicle/primitives/ntt.md b/docs/docs/icicle/primitives/ntt.md index 9816b3dc..3dd01408 100644 --- a/docs/docs/icicle/primitives/ntt.md +++ b/docs/docs/icicle/primitives/ntt.md @@ -56,7 +56,7 @@ Choosing an algorithm is heavily dependent on your use case. For example Cooley- NTT also supports two different modes `Batch NTT` and `Single NTT` -Deciding weather to use `batch NTT` vs `single NTT` is highly dependent on your application and use case. +Deciding whether to use `batch NTT` vs `single NTT` is highly dependent on your application and use case. #### Single NTT diff --git a/docs/docs/icicle/primitives/poseidon.md b/docs/docs/icicle/primitives/poseidon.md index 5626701b..3a59f06e 100644 --- a/docs/docs/icicle/primitives/poseidon.md +++ b/docs/docs/icicle/primitives/poseidon.md @@ -1,6 +1,6 @@ # Poseidon -[Poseidon](https://eprint.iacr.org/2019/458.pdf) is a popular hash in the ZK ecosystem primarily because its optimized to work over large prime fields, a common setting for ZK proofs, thereby minimizing the number of multiplicative operations required. +[Poseidon](https://eprint.iacr.org/2019/458.pdf) is a popular hash in the ZK ecosystem primarily because it's optimized to work over large prime fields, a common setting for ZK proofs, thereby minimizing the number of multiplicative operations required. Poseidon has also been specifically designed to be efficient when implemented within ZK circuits, Poseidon uses far less constraints compared to other hash functions like Keccak or SHA-256 in the context of ZK circuits. @@ -42,7 +42,7 @@ To generate a secure hash output, the algorithm goes through a series of "full r **Linear Transformation and Round Constants:** A linear transformation is performed and round constants are added. The linear transformation in partial rounds can be designed to be less computationally intensive (this is done by using a sparse matrix) than in full rounds, further optimizing the function's efficiency. -The user of Poseidon can often choose how many partial or full rounds he wishes to apply; more full rounds will increase security but degrade performance. The choice and balance is highly dependent on the use case. +The user of Poseidon can often choose how many partial or full rounds he wishes to apply; more full rounds will increase security but degrade performance. The choice and balance are highly dependent on the use case. ## Using Poseidon @@ -60,7 +60,7 @@ So for Poseidon of arity 2 and input of size 1024 * 2, we would expect 1024 elem Poseidon is extremely customizable and using different constants will produce different hashes, security levels and performance results. -We support pre-calculated and optimized constants for each of the [supported curves](../core#supported-curves-and-operations).The constants can be found [here](https://github.com/ingonyama-zk/icicle/tree/main/icicle/include/poseidon/constants) and are labeled clearly per curve `_poseidon.h`. +We support pre-calculated and optimized constants for each of the [supported curves](../core#supported-curves-and-operations). The constants can be found [here](https://github.com/ingonyama-zk/icicle/tree/main/icicle/include/poseidon/constants) and are labeled clearly per curve `_poseidon.h`. If you wish to generate your own constants you can use our python script which can be found [here](https://github.com/ingonyama-zk/icicle/tree/main/icicle/include/poseidon/constants/generate_parameters.py). @@ -135,7 +135,7 @@ impl<'a> Default for HashConfig<'a> { } ``` -In the example above `Poseidon::load(arity, &ctx).unwrap();` is used which will load the correct constants based on arity and curve. Its possible to [generate](#constants) your own constants and load them. +In the example above `Poseidon::load(arity, &ctx).unwrap();` is used which will load the correct constants based on arity and curve. It's possible to [generate](#constants) your own constants and load them. ```rust let ctx = get_default_device_context(); diff --git a/icicle/src/curves/extern.cu b/icicle/src/curves/extern.cu index 8ea5bce2..a40d24ff 100644 --- a/icicle/src/curves/extern.cu +++ b/icicle/src/curves/extern.cu @@ -20,6 +20,11 @@ extern "C" void CONCAT_EXPAND(CURVE, to_affine)(projective_t* point, affine_t* p *point_out = projective_t::to_affine(*point); } +extern "C" void CONCAT_EXPAND(CURVE, from_affine)(affine_t* point, projective_t* point_out) +{ + *point_out = projective_t::from_affine(*point); +} + extern "C" void CONCAT_EXPAND(CURVE, generate_projective_points)(projective_t* points, int size) { projective_t::rand_host_many(points, size); diff --git a/icicle/src/curves/extern_g2.cu b/icicle/src/curves/extern_g2.cu index e8daa5e1..6d1e4414 100644 --- a/icicle/src/curves/extern_g2.cu +++ b/icicle/src/curves/extern_g2.cu @@ -20,6 +20,11 @@ extern "C" void CONCAT_EXPAND(CURVE, g2_to_affine)(g2_projective_t* point, g2_af *point_out = g2_projective_t::to_affine(*point); } +extern "C" void CONCAT_EXPAND(CURVE, g2_from_affine)(g2_affine_t* point, g2_projective_t* point_out) +{ + *point_out = g2_projective_t::from_affine(*point); +} + extern "C" void CONCAT_EXPAND(CURVE, g2_generate_projective_points)(g2_projective_t* points, int size) { g2_projective_t::rand_host_many(points, size); diff --git a/wrappers/golang/core/internal/mock_curve.go b/wrappers/golang/core/internal/mock_curve.go index de21b3d9..dddbddee 100644 --- a/wrappers/golang/core/internal/mock_curve.go +++ b/wrappers/golang/core/internal/mock_curve.go @@ -28,21 +28,6 @@ func (p *MockProjective) FromLimbs(x, y, z []uint32) MockProjective { return *p } -func (p *MockProjective) FromAffine(a MockAffine) MockProjective { - z := MockBaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } - - return *p -} - type MockAffine struct { X, Y MockBaseField } @@ -68,18 +53,3 @@ func (a *MockAffine) FromLimbs(x, y []uint32) MockAffine { return *a } - -func (a MockAffine) ToProjective() MockProjective { - var z MockBaseField - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p MockProjective - return p.Zero() - } - - return MockProjective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } -} diff --git a/wrappers/golang/curves/bls12377/curve.go b/wrappers/golang/curves/bls12377/curve.go index 8083669a..43184ff5 100644 --- a/wrappers/golang/curves/bls12377/curve.go +++ b/wrappers/golang/curves/bls12377/curve.go @@ -40,17 +40,10 @@ func (p *Projective) FromLimbs(x, y, z []uint32) Projective { } func (p *Projective) FromAffine(a Affine) Projective { - z := BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(p)) + C.bls12_377_from_affine(cA, cP) return *p } @@ -65,7 +58,7 @@ func (p *Projective) ProjectiveToAffine() Affine { var a Affine cA := (*C.affine_t)(unsafe.Pointer(&a)) - cP := (*C.projective_t)(unsafe.Pointer(&p)) + cP := (*C.projective_t)(unsafe.Pointer(p)) C.bls12_377_to_affine(cP, cA) return a } @@ -111,18 +104,12 @@ func (a *Affine) FromLimbs(x, y []uint32) Affine { } func (a Affine) ToProjective() Projective { - var z BaseField + var p Projective - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p Projective - return p.Zero() - } - - return Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(&p)) + C.bls12_377_from_affine(cA, cP) + return p } func AffineFromProjective(p *Projective) Affine { diff --git a/wrappers/golang/curves/bls12377/g2/curve.go b/wrappers/golang/curves/bls12377/g2/curve.go index 7da1d271..4544e973 100644 --- a/wrappers/golang/curves/bls12377/g2/curve.go +++ b/wrappers/golang/curves/bls12377/g2/curve.go @@ -40,17 +40,10 @@ func (p *G2Projective) FromLimbs(x, y, z []uint32) G2Projective { } func (p *G2Projective) FromAffine(a G2Affine) G2Projective { - z := G2BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } + cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) + cP := (*C.g2_projective_t)(unsafe.Pointer(p)) + C.bls12_377_g2_from_affine(cA, cP) return *p } @@ -65,7 +58,7 @@ func (p *G2Projective) ProjectiveToAffine() G2Affine { var a G2Affine cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) - cP := (*C.g2_projective_t)(unsafe.Pointer(&p)) + cP := (*C.g2_projective_t)(unsafe.Pointer(p)) C.bls12_377_g2_to_affine(cP, cA) return a } @@ -111,18 +104,12 @@ func (a *G2Affine) FromLimbs(x, y []uint32) G2Affine { } func (a G2Affine) ToProjective() G2Projective { - var z G2BaseField + var p G2Projective - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p G2Projective - return p.Zero() - } - - return G2Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } + cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) + cP := (*C.g2_projective_t)(unsafe.Pointer(&p)) + C.bls12_377_g2_from_affine(cA, cP) + return p } func G2AffineFromProjective(p *G2Projective) G2Affine { diff --git a/wrappers/golang/curves/bls12377/g2/include/curve.h b/wrappers/golang/curves/bls12377/g2/include/curve.h index b136de9a..57d5e148 100644 --- a/wrappers/golang/curves/bls12377/g2/include/curve.h +++ b/wrappers/golang/curves/bls12377/g2/include/curve.h @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool bls12_377_g2_eq(g2_projective_t* point1, g2_projective_t* point2); void bls12_377_g2_to_affine(g2_projective_t* point, g2_affine_t* point_out); +void bls12_377_g2_from_affine(g2_affine_t* point, g2_projective_t* point_out); void bls12_377_g2_generate_projective_points(g2_projective_t* points, int size); void bls12_377_g2_generate_affine_points(g2_affine_t* points, int size); cudaError_t bls12_377_g2_affine_convert_montgomery(g2_affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/golang/curves/bls12377/include/curve.h b/wrappers/golang/curves/bls12377/include/curve.h index 87a0229b..6f32d1c3 100644 --- a/wrappers/golang/curves/bls12377/include/curve.h +++ b/wrappers/golang/curves/bls12377/include/curve.h @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool bls12_377_eq(projective_t* point1, projective_t* point2); void bls12_377_to_affine(projective_t* point, affine_t* point_out); +void bls12_377_from_affine(affine_t* point, projective_t* point_out); void bls12_377_generate_projective_points(projective_t* points, int size); void bls12_377_generate_affine_points(affine_t* points, int size); cudaError_t bls12_377_affine_convert_montgomery(affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/golang/curves/bls12381/curve.go b/wrappers/golang/curves/bls12381/curve.go index 02cee7b6..3b1b59ea 100644 --- a/wrappers/golang/curves/bls12381/curve.go +++ b/wrappers/golang/curves/bls12381/curve.go @@ -40,17 +40,10 @@ func (p *Projective) FromLimbs(x, y, z []uint32) Projective { } func (p *Projective) FromAffine(a Affine) Projective { - z := BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(p)) + C.bls12_381_from_affine(cA, cP) return *p } @@ -65,7 +58,7 @@ func (p *Projective) ProjectiveToAffine() Affine { var a Affine cA := (*C.affine_t)(unsafe.Pointer(&a)) - cP := (*C.projective_t)(unsafe.Pointer(&p)) + cP := (*C.projective_t)(unsafe.Pointer(p)) C.bls12_381_to_affine(cP, cA) return a } @@ -111,18 +104,12 @@ func (a *Affine) FromLimbs(x, y []uint32) Affine { } func (a Affine) ToProjective() Projective { - var z BaseField + var p Projective - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p Projective - return p.Zero() - } - - return Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(&p)) + C.bls12_381_from_affine(cA, cP) + return p } func AffineFromProjective(p *Projective) Affine { diff --git a/wrappers/golang/curves/bls12381/g2/curve.go b/wrappers/golang/curves/bls12381/g2/curve.go index d4fced65..b711be65 100644 --- a/wrappers/golang/curves/bls12381/g2/curve.go +++ b/wrappers/golang/curves/bls12381/g2/curve.go @@ -40,17 +40,10 @@ func (p *G2Projective) FromLimbs(x, y, z []uint32) G2Projective { } func (p *G2Projective) FromAffine(a G2Affine) G2Projective { - z := G2BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } + cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) + cP := (*C.g2_projective_t)(unsafe.Pointer(p)) + C.bls12_381_g2_from_affine(cA, cP) return *p } @@ -65,7 +58,7 @@ func (p *G2Projective) ProjectiveToAffine() G2Affine { var a G2Affine cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) - cP := (*C.g2_projective_t)(unsafe.Pointer(&p)) + cP := (*C.g2_projective_t)(unsafe.Pointer(p)) C.bls12_381_g2_to_affine(cP, cA) return a } @@ -111,18 +104,13 @@ func (a *G2Affine) FromLimbs(x, y []uint32) G2Affine { } func (a G2Affine) ToProjective() G2Projective { - var z G2BaseField + var p G2Projective - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p G2Projective - return p.Zero() - } + cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) + cP := (*C.g2_projective_t)(unsafe.Pointer(&p)) + C.bls12_381_g2_from_affine(cA, cP) + return p - return G2Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } } func G2AffineFromProjective(p *G2Projective) G2Affine { diff --git a/wrappers/golang/curves/bls12381/g2/include/curve.h b/wrappers/golang/curves/bls12381/g2/include/curve.h index b7710244..274f3ec1 100644 --- a/wrappers/golang/curves/bls12381/g2/include/curve.h +++ b/wrappers/golang/curves/bls12381/g2/include/curve.h @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool bls12_381_g2_eq(g2_projective_t* point1, g2_projective_t* point2); void bls12_381_g2_to_affine(g2_projective_t* point, g2_affine_t* point_out); +void bls12_381_g2_from_affine(g2_affine_t* point, g2_projective_t* point_out); void bls12_381_g2_generate_projective_points(g2_projective_t* points, int size); void bls12_381_g2_generate_affine_points(g2_affine_t* points, int size); cudaError_t bls12_381_g2_affine_convert_montgomery(g2_affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/golang/curves/bls12381/include/curve.h b/wrappers/golang/curves/bls12381/include/curve.h index 1cb3bd61..b9a50675 100644 --- a/wrappers/golang/curves/bls12381/include/curve.h +++ b/wrappers/golang/curves/bls12381/include/curve.h @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool bls12_381_eq(projective_t* point1, projective_t* point2); void bls12_381_to_affine(projective_t* point, affine_t* point_out); +void bls12_381_from_affine(affine_t* point, projective_t* point_out); void bls12_381_generate_projective_points(projective_t* points, int size); void bls12_381_generate_affine_points(affine_t* points, int size); cudaError_t bls12_381_affine_convert_montgomery(affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/golang/curves/bn254/curve.go b/wrappers/golang/curves/bn254/curve.go index 3bc94a8f..f78e0284 100644 --- a/wrappers/golang/curves/bn254/curve.go +++ b/wrappers/golang/curves/bn254/curve.go @@ -40,17 +40,10 @@ func (p *Projective) FromLimbs(x, y, z []uint32) Projective { } func (p *Projective) FromAffine(a Affine) Projective { - z := BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(p)) + C.bn254_from_affine(cA, cP) return *p } @@ -65,7 +58,7 @@ func (p *Projective) ProjectiveToAffine() Affine { var a Affine cA := (*C.affine_t)(unsafe.Pointer(&a)) - cP := (*C.projective_t)(unsafe.Pointer(&p)) + cP := (*C.projective_t)(unsafe.Pointer(p)) C.bn254_to_affine(cP, cA) return a } @@ -111,18 +104,13 @@ func (a *Affine) FromLimbs(x, y []uint32) Affine { } func (a Affine) ToProjective() Projective { - var z BaseField + var p Projective - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p Projective - return p.Zero() - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(&p)) + C.bn254_from_affine(cA, cP) + return p - return Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } } func AffineFromProjective(p *Projective) Affine { diff --git a/wrappers/golang/curves/bn254/g2/curve.go b/wrappers/golang/curves/bn254/g2/curve.go index 7ee0ec7f..72245e02 100644 --- a/wrappers/golang/curves/bn254/g2/curve.go +++ b/wrappers/golang/curves/bn254/g2/curve.go @@ -40,17 +40,10 @@ func (p *G2Projective) FromLimbs(x, y, z []uint32) G2Projective { } func (p *G2Projective) FromAffine(a G2Affine) G2Projective { - z := G2BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } + cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) + cP := (*C.g2_projective_t)(unsafe.Pointer(p)) + C.bn254_g2_from_affine(cA, cP) return *p } @@ -65,7 +58,7 @@ func (p *G2Projective) ProjectiveToAffine() G2Affine { var a G2Affine cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) - cP := (*C.g2_projective_t)(unsafe.Pointer(&p)) + cP := (*C.g2_projective_t)(unsafe.Pointer(p)) C.bn254_g2_to_affine(cP, cA) return a } @@ -111,18 +104,12 @@ func (a *G2Affine) FromLimbs(x, y []uint32) G2Affine { } func (a G2Affine) ToProjective() G2Projective { - var z G2BaseField + var p G2Projective - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p G2Projective - return p.Zero() - } - - return G2Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } + cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) + cP := (*C.g2_projective_t)(unsafe.Pointer(&p)) + C.bn254_g2_from_affine(cA, cP) + return p } func G2AffineFromProjective(p *G2Projective) G2Affine { diff --git a/wrappers/golang/curves/bn254/g2/include/curve.h b/wrappers/golang/curves/bn254/g2/include/curve.h index e8863f1e..c24deb30 100644 --- a/wrappers/golang/curves/bn254/g2/include/curve.h +++ b/wrappers/golang/curves/bn254/g2/include/curve.h @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool bn254_g2_eq(g2_projective_t* point1, g2_projective_t* point2); void bn254_g2_to_affine(g2_projective_t* point, g2_affine_t* point_out); +void bn254_g2_from_affine(g2_affine_t* point, g2_projective_t* point_out); void bn254_g2_generate_projective_points(g2_projective_t* points, int size); void bn254_g2_generate_affine_points(g2_affine_t* points, int size); cudaError_t bn254_g2_affine_convert_montgomery(g2_affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/golang/curves/bn254/include/curve.h b/wrappers/golang/curves/bn254/include/curve.h index 069600aa..ce29f587 100644 --- a/wrappers/golang/curves/bn254/include/curve.h +++ b/wrappers/golang/curves/bn254/include/curve.h @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool bn254_eq(projective_t* point1, projective_t* point2); void bn254_to_affine(projective_t* point, affine_t* point_out); +void bn254_from_affine(affine_t* point, projective_t* point_out); void bn254_generate_projective_points(projective_t* points, int size); void bn254_generate_affine_points(affine_t* points, int size); cudaError_t bn254_affine_convert_montgomery(affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/golang/curves/bw6761/curve.go b/wrappers/golang/curves/bw6761/curve.go index 2e8518be..38a68fd9 100644 --- a/wrappers/golang/curves/bw6761/curve.go +++ b/wrappers/golang/curves/bw6761/curve.go @@ -40,17 +40,10 @@ func (p *Projective) FromLimbs(x, y, z []uint32) Projective { } func (p *Projective) FromAffine(a Affine) Projective { - z := BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(p)) + C.bw6_761_from_affine(cA, cP) return *p } @@ -65,7 +58,7 @@ func (p *Projective) ProjectiveToAffine() Affine { var a Affine cA := (*C.affine_t)(unsafe.Pointer(&a)) - cP := (*C.projective_t)(unsafe.Pointer(&p)) + cP := (*C.projective_t)(unsafe.Pointer(p)) C.bw6_761_to_affine(cP, cA) return a } @@ -111,18 +104,13 @@ func (a *Affine) FromLimbs(x, y []uint32) Affine { } func (a Affine) ToProjective() Projective { - var z BaseField + var p Projective - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p Projective - return p.Zero() - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(&p)) + C.bw6_761_from_affine(cA, cP) + return p - return Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } } func AffineFromProjective(p *Projective) Affine { diff --git a/wrappers/golang/curves/bw6761/g2/curve.go b/wrappers/golang/curves/bw6761/g2/curve.go index 1433602a..f38bf134 100644 --- a/wrappers/golang/curves/bw6761/g2/curve.go +++ b/wrappers/golang/curves/bw6761/g2/curve.go @@ -40,17 +40,10 @@ func (p *G2Projective) FromLimbs(x, y, z []uint32) G2Projective { } func (p *G2Projective) FromAffine(a G2Affine) G2Projective { - z := G2BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } + cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) + cP := (*C.g2_projective_t)(unsafe.Pointer(p)) + C.bw6_761_g2_from_affine(cA, cP) return *p } @@ -65,7 +58,7 @@ func (p *G2Projective) ProjectiveToAffine() G2Affine { var a G2Affine cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) - cP := (*C.g2_projective_t)(unsafe.Pointer(&p)) + cP := (*C.g2_projective_t)(unsafe.Pointer(p)) C.bw6_761_g2_to_affine(cP, cA) return a } @@ -111,18 +104,12 @@ func (a *G2Affine) FromLimbs(x, y []uint32) G2Affine { } func (a G2Affine) ToProjective() G2Projective { - var z G2BaseField + var p G2Projective - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p G2Projective - return p.Zero() - } - - return G2Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } + cA := (*C.g2_affine_t)(unsafe.Pointer(&a)) + cP := (*C.g2_projective_t)(unsafe.Pointer(&p)) + C.bw6_761_g2_from_affine(cA, cP) + return p } func G2AffineFromProjective(p *G2Projective) G2Affine { diff --git a/wrappers/golang/curves/bw6761/g2/include/curve.h b/wrappers/golang/curves/bw6761/g2/include/curve.h index b57b55cf..8d113fc9 100644 --- a/wrappers/golang/curves/bw6761/g2/include/curve.h +++ b/wrappers/golang/curves/bw6761/g2/include/curve.h @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool bw6_761_g2_eq(g2_projective_t* point1, g2_projective_t* point2); void bw6_761_g2_to_affine(g2_projective_t* point, g2_affine_t* point_out); +void bw6_761_g2_from_affine(g2_affine_t* point, g2_projective_t* point_out); void bw6_761_g2_generate_projective_points(g2_projective_t* points, int size); void bw6_761_g2_generate_affine_points(g2_affine_t* points, int size); cudaError_t bw6_761_g2_affine_convert_montgomery(g2_affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/golang/curves/bw6761/include/curve.h b/wrappers/golang/curves/bw6761/include/curve.h index cc6e401c..ba243029 100644 --- a/wrappers/golang/curves/bw6761/include/curve.h +++ b/wrappers/golang/curves/bw6761/include/curve.h @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool bw6_761_eq(projective_t* point1, projective_t* point2); void bw6_761_to_affine(projective_t* point, affine_t* point_out); +void bw6_761_from_affine(affine_t* point, projective_t* point_out); void bw6_761_generate_projective_points(projective_t* points, int size); void bw6_761_generate_affine_points(affine_t* points, int size); cudaError_t bw6_761_affine_convert_montgomery(affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/golang/curves/grumpkin/curve.go b/wrappers/golang/curves/grumpkin/curve.go index 1079ce2e..4ad6e232 100644 --- a/wrappers/golang/curves/grumpkin/curve.go +++ b/wrappers/golang/curves/grumpkin/curve.go @@ -40,17 +40,10 @@ func (p *Projective) FromLimbs(x, y, z []uint32) Projective { } func (p *Projective) FromAffine(a Affine) Projective { - z := BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - } else { - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(p)) + C.grumpkin_from_affine(cA, cP) return *p } @@ -65,7 +58,7 @@ func (p *Projective) ProjectiveToAffine() Affine { var a Affine cA := (*C.affine_t)(unsafe.Pointer(&a)) - cP := (*C.projective_t)(unsafe.Pointer(&p)) + cP := (*C.projective_t)(unsafe.Pointer(p)) C.grumpkin_to_affine(cP, cA) return a } @@ -111,18 +104,13 @@ func (a *Affine) FromLimbs(x, y []uint32) Affine { } func (a Affine) ToProjective() Projective { - var z BaseField + var p Projective - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p Projective - return p.Zero() - } + cA := (*C.affine_t)(unsafe.Pointer(&a)) + cP := (*C.projective_t)(unsafe.Pointer(&p)) + C.grumpkin_from_affine(cA, cP) + return p - return Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } } func AffineFromProjective(p *Projective) Affine { diff --git a/wrappers/golang/curves/grumpkin/include/curve.h b/wrappers/golang/curves/grumpkin/include/curve.h index 8466982e..6005b280 100644 --- a/wrappers/golang/curves/grumpkin/include/curve.h +++ b/wrappers/golang/curves/grumpkin/include/curve.h @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool grumpkin_eq(projective_t* point1, projective_t* point2); void grumpkin_to_affine(projective_t* point, affine_t* point_out); +void grumpkin_from_affine(affine_t* point, projective_t* point_out); void grumpkin_generate_projective_points(projective_t* points, int size); void grumpkin_generate_affine_points(affine_t* points, int size); cudaError_t grumpkin_affine_convert_montgomery(affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/golang/internal/generator/curves/templates/curve.go.tmpl b/wrappers/golang/internal/generator/curves/templates/curve.go.tmpl index d02fe6a9..c411f63c 100644 --- a/wrappers/golang/internal/generator/curves/templates/curve.go.tmpl +++ b/wrappers/golang/internal/generator/curves/templates/curve.go.tmpl @@ -39,21 +39,17 @@ func (p *{{.CurvePrefix}}Projective) FromLimbs(x, y, z []uint32) {{.CurvePrefix} return *p } + + +{{if ne .CurvePrefix "Mock"}} func (p *{{.CurvePrefix}}Projective) FromAffine(a {{.CurvePrefix}}Affine) {{.CurvePrefix}}Projective { - z := {{.CurvePrefix}}BaseField{} - z.One() - - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - p.Zero() - }else{ - p.X = a.X - p.Y = a.Y - p.Z = z.One() - } - + + cA := (*C.{{toCName .CurvePrefix}}affine_t)(unsafe.Pointer(&a)) + cP := (*C.{{toCName .CurvePrefix}}projective_t)(unsafe.Pointer(p)) + C.{{.Curve}}{{toCNameBackwards .CurvePrefix}}_from_affine(cA, cP) return *p } -{{if ne .CurvePrefix "Mock"}} + func (p {{.CurvePrefix}}Projective) ProjectiveEq(p2 *{{.CurvePrefix}}Projective) bool { cP := (*C.{{toCName .CurvePrefix}}projective_t)(unsafe.Pointer(&p)) cP2 := (*C.{{toCName .CurvePrefix}}projective_t)(unsafe.Pointer(&p2)) @@ -65,7 +61,7 @@ func (p *{{.CurvePrefix}}Projective) ProjectiveToAffine() {{.CurvePrefix}}Affine var a {{.CurvePrefix}}Affine cA := (*C.{{toCName .CurvePrefix}}affine_t)(unsafe.Pointer(&a)) - cP := (*C.{{toCName .CurvePrefix}}projective_t)(unsafe.Pointer(&p)) + cP := (*C.{{toCName .CurvePrefix}}projective_t)(unsafe.Pointer(p)) C.{{.Curve}}{{toCNameBackwards .CurvePrefix}}_to_affine(cP, cA) return a } @@ -110,21 +106,17 @@ func (a *{{.CurvePrefix}}Affine) FromLimbs(x, y []uint32) {{.CurvePrefix}}Affine return *a } -func (a {{.CurvePrefix}}Affine) ToProjective() {{.CurvePrefix}}Projective { - var z {{.CurvePrefix}}BaseField - if (a.X == z.Zero()) && (a.Y == z.Zero()) { - var p {{.CurvePrefix}}Projective - return p.Zero() - } - - return {{.CurvePrefix}}Projective{ - X: a.X, - Y: a.Y, - Z: z.One(), - } -} {{if ne .CurvePrefix "Mock"}} +func (a {{.CurvePrefix}}Affine) ToProjective() {{.CurvePrefix}}Projective { + var p {{.CurvePrefix}}Projective + + cA := (*C.{{toCName .CurvePrefix}}affine_t)(unsafe.Pointer(&a)) + cP := (*C.{{toCName .CurvePrefix}}projective_t)(unsafe.Pointer(&p)) + C.{{.Curve}}{{toCNameBackwards .CurvePrefix}}_from_affine(cA, cP) + return p +} + func {{.CurvePrefix}}AffineFromProjective(p *{{.CurvePrefix}}Projective) {{.CurvePrefix}}Affine { return p.ProjectiveToAffine() } diff --git a/wrappers/golang/internal/generator/curves/templates/curve.h.tmpl b/wrappers/golang/internal/generator/curves/templates/curve.h.tmpl index 22179e6f..0dffd240 100644 --- a/wrappers/golang/internal/generator/curves/templates/curve.h.tmpl +++ b/wrappers/golang/internal/generator/curves/templates/curve.h.tmpl @@ -14,6 +14,7 @@ typedef struct DeviceContext DeviceContext; bool {{.Curve}}{{toCNameBackwards .CurvePrefix}}_eq({{toCName .CurvePrefix}}projective_t* point1, {{toCName .CurvePrefix}}projective_t* point2); void {{.Curve}}{{toCNameBackwards .CurvePrefix}}_to_affine({{toCName .CurvePrefix}}projective_t* point, {{toCName .CurvePrefix}}affine_t* point_out); +void {{.Curve}}{{toCNameBackwards .CurvePrefix}}_from_affine({{toCName .CurvePrefix}}affine_t* point, {{toCName .CurvePrefix}}projective_t* point_out); void {{.Curve}}{{toCNameBackwards .CurvePrefix}}_generate_projective_points({{toCName .CurvePrefix}}projective_t* points, int size); void {{.Curve}}{{toCNameBackwards .CurvePrefix}}_generate_affine_points({{toCName .CurvePrefix}}affine_t* points, int size); cudaError_t {{.Curve}}{{toCNameBackwards .CurvePrefix}}_affine_convert_montgomery({{toCName .CurvePrefix}}affine_t* points, size_t n, bool is_into, DeviceContext* ctx); diff --git a/wrappers/rust/icicle-core/src/curve.rs b/wrappers/rust/icicle-core/src/curve.rs index c0b82d11..a0bf70bc 100644 --- a/wrappers/rust/icicle-core/src/curve.rs +++ b/wrappers/rust/icicle-core/src/curve.rs @@ -22,6 +22,8 @@ pub trait Curve: Debug + PartialEq + Copy + Clone { #[doc(hidden)] fn to_affine(point: *const Projective, point_aff: *mut Affine); #[doc(hidden)] + fn from_affine(point: *const Affine, point_proj: *mut Projective); + #[doc(hidden)] fn generate_random_projective_points(size: usize) -> Vec>; #[doc(hidden)] fn generate_random_affine_points(size: usize) -> Vec>; @@ -79,27 +81,17 @@ impl Affine { } pub fn to_projective(&self) -> Projective { - if *self == Self::zero() { - return Projective::::zero(); - } - Projective { - x: self.x, - y: self.y, - z: C::BaseField::one(), - } + let mut proj = Projective::::zero(); + C::from_affine(self as *const Self, &mut proj as *mut Projective); + proj } } impl From> for Projective { fn from(item: Affine) -> Self { - if item == (Affine::::zero()) { - return Self::zero(); - } - Self { - x: item.x, - y: item.y, - z: C::BaseField::one(), - } + let mut proj = Self::zero(); + C::from_affine(&item as *const Affine, &mut proj as *mut Self); + proj } } @@ -282,6 +274,8 @@ macro_rules! impl_curve { pub(crate) fn eq(point1: *const $projective_type, point2: *const $projective_type) -> bool; #[link_name = concat!($curve_prefix, "_to_affine")] pub(crate) fn proj_to_affine(point: *const $projective_type, point_out: *mut $affine_type); + #[link_name = concat!($curve_prefix, "_from_affine")] + pub(crate) fn proj_from_affine(point: *const $affine_type, point_out: *mut $projective_type); #[link_name = concat!($curve_prefix, "_generate_projective_points")] pub(crate) fn generate_projective_points(points: *mut $projective_type, size: usize); #[link_name = concat!($curve_prefix, "_generate_affine_points")] @@ -315,6 +309,10 @@ macro_rules! impl_curve { unsafe { $curve_prefix_ident::proj_to_affine(point, point_out) }; } + fn from_affine(point: *const $affine_type, point_out: *mut $projective_type) { + unsafe { $curve_prefix_ident::proj_from_affine(point, point_out) }; + } + fn generate_random_projective_points(size: usize) -> Vec<$projective_type> { let mut res = vec![$projective_type::zero(); size]; unsafe {