Add implementation of q-order subgroup checking for G1Affine/G2Affine.
This commit is contained in:
parent
526209abdf
commit
b893a04fbe
|
@ -21,6 +21,9 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|||
c.bench_function(&format!("{} scalar multiplication", name), move |b| {
|
||||
b.iter(|| black_box(a) * black_box(s))
|
||||
});
|
||||
c.bench_function(&format!("{} subgroup check", name), move |b| {
|
||||
b.iter(|| black_box(a).is_torsion_free())
|
||||
});
|
||||
}
|
||||
|
||||
// G1Projective
|
||||
|
@ -66,6 +69,9 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|||
c.bench_function(&format!("{} scalar multiplication", name), move |b| {
|
||||
b.iter(|| black_box(a) * black_box(s))
|
||||
});
|
||||
c.bench_function(&format!("{} subgroup check", name), move |b| {
|
||||
b.iter(|| black_box(a).is_torsion_free())
|
||||
});
|
||||
}
|
||||
|
||||
// G2Projective
|
||||
|
|
42
src/g1.rs
42
src/g1.rs
|
@ -186,6 +186,21 @@ impl G1Affine {
|
|||
self.infinity
|
||||
}
|
||||
|
||||
/// Returns true if this point is free of an $h$-torsion component, and so it
|
||||
/// exists within the $q$-order subgroup $\mathbb{G}_1$. This should always return true
|
||||
/// unless an "unchecked" API was used.
|
||||
pub fn is_torsion_free(&self) -> Choice {
|
||||
const FQ_MODULUS_BYTES: [u8; 32] = [
|
||||
1, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9, 8,
|
||||
216, 57, 51, 72, 125, 157, 41, 83, 167, 237, 115,
|
||||
];
|
||||
|
||||
// Clear the r-torsion from the point and check if it is the identity
|
||||
G1Projective::from(*self)
|
||||
.multiply(&FQ_MODULUS_BYTES)
|
||||
.is_identity()
|
||||
}
|
||||
|
||||
/// Returns true if this point is on the curve. This should always return
|
||||
/// true unless an "unchecked" API was used.
|
||||
pub fn is_on_curve(&self) -> Choice {
|
||||
|
@ -1041,3 +1056,30 @@ fn test_affine_scalar_multiplication() {
|
|||
|
||||
assert_eq!(G1Affine::from(g * a) * b, g * c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_torsion_free() {
|
||||
let a = G1Affine {
|
||||
x: Fp::from_raw_unchecked([
|
||||
0xabaf895b97e43c8,
|
||||
0xba4c6432eb9b61b0,
|
||||
0x12506f52adfe307f,
|
||||
0x75028c3439336b72,
|
||||
0x84744f05b8e9bd71,
|
||||
0x113d554fb09554f7,
|
||||
]),
|
||||
y: Fp::from_raw_unchecked([
|
||||
0x73e90e88f5cf01c0,
|
||||
0x37007b65dd3197e2,
|
||||
0x5cf9a1992f0d7c78,
|
||||
0x4f83c10b9eb3330d,
|
||||
0xf6a63f6f07f60961,
|
||||
0xc53b5b97e634df3,
|
||||
]),
|
||||
infinity: Choice::from(0u8),
|
||||
};
|
||||
assert!(!bool::from(a.is_torsion_free()));
|
||||
|
||||
assert!(bool::from(G1Affine::identity().is_torsion_free()));
|
||||
assert!(bool::from(G1Affine::generator().is_torsion_free()));
|
||||
}
|
||||
|
|
62
src/g2.rs
62
src/g2.rs
|
@ -217,6 +217,21 @@ impl G2Affine {
|
|||
self.infinity
|
||||
}
|
||||
|
||||
/// Returns true if this point is free of an $h$-torsion component, and so it
|
||||
/// exists within the $q$-order subgroup $\mathbb{G}_2$. This should always return true
|
||||
/// unless an "unchecked" API was used.
|
||||
pub fn is_torsion_free(&self) -> Choice {
|
||||
const FQ_MODULUS_BYTES: [u8; 32] = [
|
||||
1, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9, 8,
|
||||
216, 57, 51, 72, 125, 157, 41, 83, 167, 237, 115,
|
||||
];
|
||||
|
||||
// Clear the r-torsion from the point and check if it is the identity
|
||||
G2Projective::from(*self)
|
||||
.multiply(&FQ_MODULUS_BYTES)
|
||||
.is_identity()
|
||||
}
|
||||
|
||||
/// Returns true if this point is on the curve. This should always return
|
||||
/// true unless an "unchecked" API was used.
|
||||
pub fn is_on_curve(&self) -> Choice {
|
||||
|
@ -1228,3 +1243,50 @@ fn test_affine_scalar_multiplication() {
|
|||
|
||||
assert_eq!(G2Affine::from(g * a) * b, g * c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_torsion_free() {
|
||||
let a = G2Affine {
|
||||
x: Fp2 {
|
||||
c0: Fp::from_raw_unchecked([
|
||||
0x89f550c813db6431,
|
||||
0xa50be8c456cd8a1a,
|
||||
0xa45b374114cae851,
|
||||
0xbb6190f5bf7fff63,
|
||||
0x970ca02c3ba80bc7,
|
||||
0x2b85d24e840fbac,
|
||||
]),
|
||||
c1: Fp::from_raw_unchecked([
|
||||
0x6888bc53d70716dc,
|
||||
0x3dea6b4117682d70,
|
||||
0xd8f5f930500ca354,
|
||||
0x6b5ecb6556f5c155,
|
||||
0xc96bef0434778ab0,
|
||||
0x5081505515006ad,
|
||||
]),
|
||||
},
|
||||
y: Fp2 {
|
||||
c0: Fp::from_raw_unchecked([
|
||||
0x3cf1ea0d434b0f40,
|
||||
0x1a0dc610e603e333,
|
||||
0x7f89956160c72fa0,
|
||||
0x25ee03decf6431c5,
|
||||
0xeee8e206ec0fe137,
|
||||
0x97592b226dfef28,
|
||||
]),
|
||||
c1: Fp::from_raw_unchecked([
|
||||
0x71e8bb5f29247367,
|
||||
0xa5fe049e211831ce,
|
||||
0xce6b354502a3896,
|
||||
0x93b012000997314e,
|
||||
0x6759f3b6aa5b42ac,
|
||||
0x156944c4dfe92bbb,
|
||||
]),
|
||||
},
|
||||
infinity: Choice::from(0u8),
|
||||
};
|
||||
assert!(!bool::from(a.is_torsion_free()));
|
||||
|
||||
assert!(bool::from(G2Affine::identity().is_torsion_free()));
|
||||
assert!(bool::from(G2Affine::generator().is_torsion_free()));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue