Add implementation of point doubling.
This commit is contained in:
parent
0ccb2fbff0
commit
4678a67ce6
|
@ -32,6 +32,9 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|||
c.bench_function(&format!("{} to affine", name), move |b| {
|
||||
b.iter(|| G1Affine::from(black_box(a)))
|
||||
});
|
||||
c.bench_function(&format!("{} doubling", name), move |b| {
|
||||
b.iter(|| black_box(a).double())
|
||||
});
|
||||
}
|
||||
|
||||
// G2Affine
|
||||
|
@ -59,6 +62,9 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|||
c.bench_function(&format!("{} to affine", name), move |b| {
|
||||
b.iter(|| G2Affine::from(black_box(a)))
|
||||
});
|
||||
c.bench_function(&format!("{} doubling", name), move |b| {
|
||||
b.iter(|| black_box(a).double())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
69
src/g1.rs
69
src/g1.rs
|
@ -226,6 +226,38 @@ impl G1Projective {
|
|||
}
|
||||
}
|
||||
|
||||
/// Computes the doubling of this point.
|
||||
pub fn double(&self) -> G1Projective {
|
||||
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
|
||||
//
|
||||
// There are no points of order 2.
|
||||
|
||||
let a = self.x.square();
|
||||
let b = self.y.square();
|
||||
let c = b.square();
|
||||
let d = self.x + b;
|
||||
let d = d.square();
|
||||
let d = d - a - c;
|
||||
let d = d + d;
|
||||
let e = a + a + a;
|
||||
let f = e.square();
|
||||
let z3 = self.z * self.y;
|
||||
let z3 = z3 + z3;
|
||||
let x3 = f - (d + d);
|
||||
let c = c + c;
|
||||
let c = c + c;
|
||||
let c = c + c;
|
||||
let y3 = e * (d - x3) - c;
|
||||
|
||||
let tmp = G1Projective {
|
||||
x: x3,
|
||||
y: y3,
|
||||
z: z3,
|
||||
};
|
||||
|
||||
G1Projective::conditional_select(&tmp, &G1Projective::identity(), self.is_identity())
|
||||
}
|
||||
|
||||
/// Returns true if this element is the identity (the point at infinity).
|
||||
#[inline]
|
||||
pub fn is_identity(&self) -> Choice {
|
||||
|
@ -392,3 +424,40 @@ fn test_affine_to_projective() {
|
|||
assert!(bool::from(G1Projective::from(b).is_on_curve()));
|
||||
assert!(bool::from(G1Projective::from(b).is_identity()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_doubling() {
|
||||
{
|
||||
let tmp = G1Projective::identity().double();
|
||||
assert!(bool::from(tmp.is_identity()));
|
||||
assert!(bool::from(tmp.is_on_curve()));
|
||||
}
|
||||
{
|
||||
let tmp = G1Projective::generator().double();
|
||||
assert!(!bool::from(tmp.is_identity()));
|
||||
assert!(bool::from(tmp.is_on_curve()));
|
||||
|
||||
assert_eq!(
|
||||
G1Affine::from(tmp),
|
||||
G1Affine {
|
||||
x: Fp::from_raw_unchecked([
|
||||
0x53e978ce58a9ba3c,
|
||||
0x3ea0583c4f3d65f9,
|
||||
0x4d20bb47f0012960,
|
||||
0xa54c664ae5b2b5d9,
|
||||
0x26b552a39d7eb21f,
|
||||
0x8895d26e68785
|
||||
]),
|
||||
y: Fp::from_raw_unchecked([
|
||||
0x70110b3298293940,
|
||||
0xda33c5393f1f6afc,
|
||||
0xb86edfd16a5aa785,
|
||||
0xaec6d1c9e7b1c895,
|
||||
0x25cfc2b522d11720,
|
||||
0x6361c83f8d09b15
|
||||
]),
|
||||
infinity: Choice::from(0u8)
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
89
src/g2.rs
89
src/g2.rs
|
@ -277,6 +277,38 @@ impl G2Projective {
|
|||
}
|
||||
}
|
||||
|
||||
/// Computes the doubling of this point.
|
||||
pub fn double(&self) -> G2Projective {
|
||||
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
|
||||
//
|
||||
// There are no points of order 2.
|
||||
|
||||
let a = self.x.square();
|
||||
let b = self.y.square();
|
||||
let c = b.square();
|
||||
let d = self.x + b;
|
||||
let d = d.square();
|
||||
let d = d - a - c;
|
||||
let d = d + d;
|
||||
let e = a + a + a;
|
||||
let f = e.square();
|
||||
let z3 = self.z * self.y;
|
||||
let z3 = z3 + z3;
|
||||
let x3 = f - (d + d);
|
||||
let c = c + c;
|
||||
let c = c + c;
|
||||
let c = c + c;
|
||||
let y3 = e * (d - x3) - c;
|
||||
|
||||
let tmp = G2Projective {
|
||||
x: x3,
|
||||
y: y3,
|
||||
z: z3,
|
||||
};
|
||||
|
||||
G2Projective::conditional_select(&tmp, &G2Projective::identity(), self.is_identity())
|
||||
}
|
||||
|
||||
/// Returns true if this element is the identity (the point at infinity).
|
||||
#[inline]
|
||||
pub fn is_identity(&self) -> Choice {
|
||||
|
@ -473,3 +505,60 @@ fn test_affine_to_projective() {
|
|||
assert!(bool::from(G2Projective::from(b).is_on_curve()));
|
||||
assert!(bool::from(G2Projective::from(b).is_identity()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_doubling() {
|
||||
{
|
||||
let tmp = G2Projective::identity().double();
|
||||
assert!(bool::from(tmp.is_identity()));
|
||||
assert!(bool::from(tmp.is_on_curve()));
|
||||
}
|
||||
{
|
||||
let tmp = G2Projective::generator().double();
|
||||
assert!(!bool::from(tmp.is_identity()));
|
||||
assert!(bool::from(tmp.is_on_curve()));
|
||||
|
||||
assert_eq!(
|
||||
G2Affine::from(tmp),
|
||||
G2Affine {
|
||||
x: Fp2 {
|
||||
c0: Fp::from_raw_unchecked([
|
||||
0xe9d9e2da9620f98b,
|
||||
0x54f1199346b97f36,
|
||||
0x3db3b820376bed27,
|
||||
0xcfdb31c9b0b64f4c,
|
||||
0x41d7c12786354493,
|
||||
0x5710794c255c064
|
||||
]),
|
||||
c1: Fp::from_raw_unchecked([
|
||||
0xd6c1d3ca6ea0d06e,
|
||||
0xda0cbd905595489f,
|
||||
0x4f5352d43479221d,
|
||||
0x8ade5d736f8c97e0,
|
||||
0x48cc8433925ef70e,
|
||||
0x8d7ea71ea91ef81
|
||||
]),
|
||||
},
|
||||
y: Fp2 {
|
||||
c0: Fp::from_raw_unchecked([
|
||||
0x15ba26eb4b0d186f,
|
||||
0xd086d64b7e9e01e,
|
||||
0xc8b848dd652f4c78,
|
||||
0xeecf46a6123bae4f,
|
||||
0x255e8dd8b6dc812a,
|
||||
0x164142af21dcf93f
|
||||
]),
|
||||
c1: Fp::from_raw_unchecked([
|
||||
0xf9b4a1a895984db4,
|
||||
0xd417b114cccff748,
|
||||
0x6856301fc89f086e,
|
||||
0x41c777878931e3da,
|
||||
0x3556b155066a2105,
|
||||
0xacf7d325cb89cf
|
||||
]),
|
||||
},
|
||||
infinity: Choice::from(0u8)
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue