Add implementation of point doubling.

This commit is contained in:
Sean Bowe 2019-08-11 12:35:25 -06:00
parent 0ccb2fbff0
commit 4678a67ce6
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
3 changed files with 164 additions and 0 deletions

View File

@ -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())
});
}
}

View File

@ -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)
}
);
}
}

View File

@ -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)
}
);
}
}