Use mixed addition for Sinsemilla bases

Performance improvements:
- MerkleCRH:  ~5%
- Commit^ivk: ~1%
- NoteCommit: ~3%
This commit is contained in:
Jack Grigg 2021-08-12 15:43:19 +01:00
parent 6197a0ef62
commit 9f3c9a7e60
2 changed files with 28 additions and 3 deletions

View File

@ -1,6 +1,6 @@
//! The Sinsemilla hash function and commitment scheme.
use group::{prime::PrimeCurveAffine, Wnaf};
use group::Wnaf;
use halo2::arithmetic::{CurveAffine, CurveExt};
use pasta_curves::pallas;
use subtle::CtOption;
@ -120,7 +120,7 @@ impl HashDomain {
.chunks(K)
.fold(IncompletePoint::from(self.Q), |acc, chunk| {
let (S_x, S_y) = SINSEMILLA_S[lebs2ip_k(chunk) as usize];
let S_chunk = pallas::Affine::from_xy(S_x, S_y).unwrap().to_curve();
let S_chunk = pallas::Affine::from_xy(S_x, S_y).unwrap();
(acc + S_chunk) + acc
})
}

View File

@ -1,6 +1,6 @@
use std::ops::Add;
use group::Group;
use group::{cofactor::CofactorCurveAffine, Group};
use pasta_curves::pallas;
use subtle::{ConstantTimeEq, CtOption};
@ -53,3 +53,28 @@ impl Add<pallas::Point> for IncompletePoint {
self + IncompletePoint(CtOption::new(rhs, 1.into()))
}
}
impl Add<pallas::Affine> for IncompletePoint {
type Output = IncompletePoint;
/// Specialisation of incomplete addition for mixed addition.
fn add(self, rhs: pallas::Affine) -> Self::Output {
// ⊥ ⊹ ⊥ = ⊥
// ⊥ ⊹ P = ⊥
IncompletePoint(self.0.and_then(|p| {
// P ⊹ ⊥ = ⊥ is satisfied by definition.
let q = rhs.to_curve();
// 0 ⊹ 0 = ⊥
// 0 ⊹ P = ⊥
// P ⊹ 0 = ⊥
// (x, y) ⊹ (x', y') = ⊥ if x == x'
// (x, y) ⊹ (x', y') = (x, y) + (x', y') if x != x'
CtOption::new(
// Use mixed addition for efficiency.
p + rhs,
!(p.is_identity() | q.is_identity() | p.ct_eq(&q) | p.ct_eq(&-q)),
)
}))
}
}