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

Add trait to serialize field and curve objects directly into raw bytes without Montgomery reduction #10

Merged
Merged
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "halo2curves"
version = "0.2.1"
version = "0.3.1"
authors = [
"Sean Bowe <ewillbefull@gmail.com>",
"Jack Grigg <jack@z.cash>",
Expand All @@ -13,6 +13,10 @@ repository = "https://github.com/kilic/pairing"
readme = "README.md"
description = "Elliptic curve implementations and wrappers for halo2 library"

[[bench]]
name = "less_than"
harness = false

[dev-dependencies]
criterion = { version = "0.3", features = ["html_reports"] }
rand_xorshift = "0.3"
Expand Down
64 changes: 64 additions & 0 deletions benches/less_than.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#![allow(unused)]

use criterion::BenchmarkId;

/// Compute a - (b + borrow), returning the result and the new borrow.
#[inline(always)]
const fn sbb(a: u64, b: u64, borrow: u64) -> (u64, u64) {
let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128));
(ret as u64, (ret >> 64) as u64)
}

#[inline(always)]
fn is_less_than(x: &[u64; 4], y: &[u64; 4]) -> bool {
match x[3].cmp(&y[3]) {
core::cmp::Ordering::Less => return true,
core::cmp::Ordering::Greater => return false,
_ => {}
}
match x[2].cmp(&y[2]) {
core::cmp::Ordering::Less => return true,
core::cmp::Ordering::Greater => return false,
_ => {}
}
match x[1].cmp(&y[1]) {
core::cmp::Ordering::Less => return true,
core::cmp::Ordering::Greater => return false,
_ => {}
}
x[0].lt(&y[0])
}

#[inline(always)]
fn check_underflow(x: &[u64; 4], y: &[u64; 4]) -> bool {
let (_, borrow) = sbb(x[0], y[0], 0);
let (_, borrow) = sbb(x[1], y[1], borrow);
let (_, borrow) = sbb(x[2], y[2], borrow);
let (_, borrow) = sbb(x[3], y[3], borrow);
borrow >> 63 == 1
}

use criterion::{criterion_group, criterion_main, Criterion};

pub fn criterion_benchmark(c: &mut Criterion) {
let x: [u64; 4] = [(); 4].map(|_| rand::random());
let y: [u64; 4] = [(); 4].map(|_| rand::random());

let mut group = c.benchmark_group("Big less than methods");

group.bench_with_input(
BenchmarkId::new("is_less_than", ""),
&(x, y),
|b, (x, y)| b.iter(|| is_less_than(x, y)),
);

group.bench_with_input(
BenchmarkId::new("check_underflow", ""),
&(x, y),
|b, (x, y)| b.iter(|| check_underflow(x, y)),
);
group.finish();
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
7 changes: 7 additions & 0 deletions src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ pub trait CurveAffineExt: pasta_curves::arithmetic::CurveAffine {
bases: &[Self],
base_positions: &[u32],
);

/// Unlike the `Coordinates` trait, this just returns the raw affine coordinates without checking `is_on_curve`
fn into_coordinates(self) -> (Self::Base, Self::Base) {
// fallback implementation
let coordinates = self.coordinates().unwrap();
jonathanpwang marked this conversation as resolved.
Show resolved Hide resolved
(*coordinates.x(), *coordinates.y())
}
}

pub(crate) fn sqrt_tonelli_shanks<F: ff::PrimeField, S: AsRef<[u64]>>(
Expand Down
Loading