Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement From on EC structs #4148

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 70 additions & 20 deletions noir_stdlib/src/ec/montcurve.nr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod affine {
use crate::ec::sqrt;
use crate::ec::ZETA;
use crate::cmp::Eq;
use crate::from::From;

// Curve specification
struct Curve { // Montgomery Curve configuration (ky^2 = x^3 + j*x^2 + x)
Expand Down Expand Up @@ -41,12 +42,7 @@ mod affine {

// Conversion to CurveGroup coordinates
fn into_group(self) -> curvegroup::Point {
if self.is_zero() {
curvegroup::Point::zero()
} else {
let (x,y) = (self.x, self.y);
curvegroup::Point::new(x,y,1)
}
self.into()
}

// Additive identity
Expand Down Expand Up @@ -79,6 +75,31 @@ mod affine {
}
}

impl From<curvegroup::Point> for Point {
fn from(input: curvegroup::Point) -> Point {
if input.is_zero() {
Point::zero()
} else {
let (x,y,z) = (input.x, input.y, input.z);
Point::new(x/z, y/z)
}
}
}

impl From<TEPoint> for Point {
fn from(input: TEPoint) -> Point {
if input.is_zero() {
Point::zero()
} else {
let TEPoint {x, y} = input;
let x0 = (1+y)/(1-y);
let y0 = (1+y)/(x*(1-y));

Point::new(x0,y0)
}
}
}

impl Curve {
// Curve constructor
pub fn new(j: Field, k: Field, gen: Point) -> Self {
Expand All @@ -96,7 +117,7 @@ mod affine {

// Conversion to CurveGroup coordinates
fn into_group(self) -> curvegroup::Curve {
curvegroup::Curve::new(self.j, self.k, self.gen.into_group())
self.into()
}

// Membership check
Expand Down Expand Up @@ -211,6 +232,22 @@ mod affine {
self.map_from_swcurve(self.into_swcurve().swu_map(z,u))
}
}

impl From<curvegroup::Curve> for Curve {
fn from(input: curvegroup::Curve) -> Curve {
Curve::new(input.j, input.k, input.gen.into())
}
}

impl From<TECurve> for Curve {
fn from(input: TECurve) -> Curve {
let j = 2*(input.a + input.d)/(input.a - input.d);
let k = 4/(input.a - input.d);
let gen_montcurve = input.gen.into();

Curve::new(j, k, gen_montcurve)
}
}
}
mod curvegroup {
// Affine representation of Montgomery curves
Expand All @@ -223,6 +260,7 @@ mod curvegroup {
use crate::ec::tecurve::curvegroup::Curve as TECurve;
use crate::ec::tecurve::curvegroup::Point as TEPoint;
use crate::cmp::Eq;
use crate::from::From;

struct Curve { // Montgomery Curve configuration (ky^2 z = x*(x^2 + j*x*z + z*z))
j: Field,
Expand Down Expand Up @@ -250,12 +288,7 @@ mod curvegroup {

// Conversion to affine coordinates
fn into_affine(self) -> affine::Point {
if self.is_zero() {
affine::Point::zero()
} else {
let (x,y,z) = (self.x, self.y, self.z);
affine::Point::new(x/z, y/z)
}
self.into()
}

// Additive identity
Expand All @@ -272,7 +305,7 @@ mod curvegroup {

// Map into equivalent Twisted Edwards curve
fn into_tecurve(self) -> TEPoint {
self.into_affine().into_tecurve().into_group()
self.into_affine().into_tecurve().into()
}
}

Expand All @@ -282,6 +315,17 @@ mod curvegroup {
}
}

impl From<affine::Point> for Point {
fn from(input: affine::Point) -> Point {
if input.is_zero() {
Point::zero()
} else {
let (x,y) = (input.x, input.y);
Point::new(x,y,1)
}
}
}

impl Curve {
// Curve constructor
pub fn new(j: Field, k: Field, gen: Point) -> Self {
Expand All @@ -299,7 +343,7 @@ mod curvegroup {

// Conversion to affine coordinates
fn into_affine(self) -> affine::Curve {
affine::Curve::new(self.j, self.k, self.gen.into_affine())
self.into()
}

// Membership check
Expand All @@ -312,7 +356,7 @@ mod curvegroup {

// Point addition
pub fn add(self, p1: Point, p2: Point) -> Point {
self.into_affine().add(p1.into_affine(), p2.into_affine()).into_group()
self.into_affine().add(p1.into(), p2.into()).into()
}

// Scalar multiplication with scalar represented by a bit array (little-endian convention).
Expand Down Expand Up @@ -361,22 +405,28 @@ mod curvegroup {

// Point mapping into equivalent Short Weierstraß curve
pub fn map_into_swcurve(self, p: Point) -> SWPoint {
self.into_affine().map_into_swcurve(p.into_affine()).into_group()
self.into_affine().map_into_swcurve(p.into()).into()
}

// Point mapping from equivalent Short Weierstraß curve
fn map_from_swcurve(self, p: SWPoint) -> Point {
self.into_affine().map_from_swcurve(p.into_affine()).into_group()
self.into_affine().map_from_swcurve(p.into()).into()
}

// Elligator 2 map-to-curve method
fn elligator2_map(self, u: Field) -> Point {
self.into_affine().elligator2_map(u).into_group()
self.into_affine().elligator2_map(u).into()
}

// SWU map-to-curve method (via rational map)
fn swu_map(self, z: Field, u: Field) -> Point {
self.into_affine().swu_map(z,u).into_group()
self.into_affine().swu_map(z,u).into()
}
}

impl From<affine::Curve> for Curve {
fn from(input: affine::Curve) -> Curve {
Curve::new(input.j, input.k, input.gen.into())
}
}
}
75 changes: 50 additions & 25 deletions noir_stdlib/src/ec/swcurve.nr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod affine {
use crate::ec::is_square;
use crate::ec::sqrt;
use crate::cmp::Eq;
use crate::from::From;

// Curve specification
struct Curve { // Short Weierstraß curve
Expand Down Expand Up @@ -37,13 +38,7 @@ mod affine {

// Conversion to CurveGroup coordinates
fn into_group(self) -> curvegroup::Point {
let Self {x, y, infty} = self;

if infty {
curvegroup::Point::zero()
} else {
curvegroup::Point::new(x, y, 1)
}
self.into()
}

// Additive identity
Expand All @@ -68,6 +63,18 @@ mod affine {
}
}

impl From<curvegroup::Point> for Point {
fn from(input: curvegroup::Point) -> Point {
let curvegroup::Point {x, y, z} = input;

if z == 0 {
Point::zero()
} else {
Point::new(x/(z*z), y/(z*z*z))
}
}
}

impl Curve {
// Curve constructor
pub fn new(a: Field, b: Field, gen: Point) -> Curve {
Expand All @@ -84,9 +91,7 @@ mod affine {

// Conversion to CurveGroup coordinates
fn into_group(self) -> curvegroup::Curve {
let Curve{a, b, gen} = self;

curvegroup::Curve {a, b, gen: gen.into_group()}
self.into()
}

// Membership check
Expand All @@ -97,7 +102,7 @@ mod affine {

// Point addition, implemented in terms of mixed addition for reasons of efficiency
pub fn add(self, p1: Point, p2: Point) -> Point {
self.mixed_add(p1, p2.into_group()).into_affine()
self.mixed_add(p1, p2.into()).into()
}

// Mixed point addition, i.e. first argument in affine, second in CurveGroup coordinates.
Expand All @@ -118,7 +123,7 @@ mod affine {
if s1 != s2 {
curvegroup::Point::zero()
} else {
self.into_group().double(p2)
curvegroup::Curve::from(self).double(p2)
}
} else
{
Expand All @@ -136,12 +141,12 @@ mod affine {
// Scalar multiplication with scalar represented by a bit array (little-endian convention).
// If k is the natural number represented by `bits`, then this computes p + ... + p k times.
fn bit_mul<N>(self, bits: [u1; N], p: Point) -> Point {
self.into_group().bit_mul(bits, p.into_group()).into_affine()
self.into_group().bit_mul(bits, p.into()).into()
}

// Scalar multiplication (p + ... + p n times)
pub fn mul(self, n: Field, p: Point) -> Point {
self.into_group().mul(n, p.into_group()).into_affine()
self.into_group().mul(n, p.into()).into()
}

// Multi-scalar multiplication (n[0]*p[0] + ... + n[N]*p[N], where * denotes scalar multiplication)
Expand Down Expand Up @@ -178,6 +183,14 @@ mod affine {
Point::new(x, if u.sgn0() != y.sgn0() {0-y} else {y})
}
}

impl From<curvegroup::Curve> for Curve {
fn from(input: curvegroup::Curve) -> Curve {
let curvegroup::Curve {a, b, gen} = input;

Curve {a, b, gen: gen.into()}
}
}
}

mod curvegroup {
Expand All @@ -186,6 +199,7 @@ mod curvegroup {
// See <https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates> for details.
use crate::ec::swcurve::affine;
use crate::cmp::Eq;
use crate::from::From;

// Curve specification
struct Curve { // Short Weierstraß curve
Expand Down Expand Up @@ -215,21 +229,14 @@ mod curvegroup {

// Conversion to affine coordinates
pub fn into_affine(self) -> affine::Point {
let Self {x, y, z} = self;

if z == 0 {
affine::Point::zero()
} else {
affine::Point::new(x/(z*z), y/(z*z*z))
}
self.into()
}

// Additive identity
pub fn zero() -> Self {
Self {x: 0, y: 0, z: 0}
}


// Negation
fn negate(self) -> Self {
let Self {x, y, z} = self;
Expand All @@ -246,6 +253,18 @@ mod curvegroup {
}
}

impl From<affine::Point> for Point {
fn from(input: affine::Point) -> Point {
let affine::Point {x, y, infty} = input;

if infty {
Point::zero()
} else {
Point::new(x, y, 1)
}
}
}

impl Curve {
// Curve constructor
pub fn new(a: Field, b: Field, gen: Point) -> Curve {
Expand All @@ -262,9 +281,7 @@ mod curvegroup {

// Conversion to affine coordinates
pub fn into_affine(self) -> affine::Curve {
let Curve{a, b, gen} = self;

affine::Curve {a, b, gen: gen.into_affine()}
self.into()
}

// Membership check
Expand Down Expand Up @@ -378,4 +395,12 @@ mod curvegroup {
self.into_affine().swu_map(z,u).into_group()
}
}

impl From<affine::Curve> for Curve {
fn from(input: affine::Curve) -> Curve {
let affine::Curve {a, b, gen} = input;

Curve {a, b, gen: gen.into()}
}
}
}
Loading
Loading