2021-04-19 15:02:59 -07:00
|
|
|
|
use std::ops::Add;
|
|
|
|
|
|
2023-07-29 12:10:20 -07:00
|
|
|
|
use group::{CurveAffine, Group};
|
2021-04-21 16:59:55 -07:00
|
|
|
|
use pasta_curves::pallas;
|
2021-04-19 15:02:59 -07:00
|
|
|
|
use subtle::{ConstantTimeEq, CtOption};
|
|
|
|
|
|
|
|
|
|
/// P ∪ {⊥}
|
|
|
|
|
///
|
|
|
|
|
/// Simulated incomplete addition built over complete addition.
|
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
|
pub(super) struct IncompletePoint(CtOption<pallas::Point>);
|
|
|
|
|
|
|
|
|
|
impl From<pallas::Point> for IncompletePoint {
|
|
|
|
|
fn from(p: pallas::Point) -> Self {
|
|
|
|
|
IncompletePoint(CtOption::new(p, 1.into()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<IncompletePoint> for CtOption<pallas::Point> {
|
|
|
|
|
fn from(p: IncompletePoint) -> Self {
|
|
|
|
|
p.0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Add for IncompletePoint {
|
|
|
|
|
type Output = IncompletePoint;
|
|
|
|
|
|
2021-04-21 17:08:51 -07:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-04-19 15:02:59 -07:00
|
|
|
|
fn add(self, rhs: Self) -> Self::Output {
|
2021-08-12 13:33:19 -07:00
|
|
|
|
// ⊥ ⸭ ⊥ = ⊥
|
|
|
|
|
// ⊥ ⸭ P = ⊥
|
2021-04-19 15:02:59 -07:00
|
|
|
|
IncompletePoint(self.0.and_then(|p| {
|
2021-08-12 13:33:19 -07:00
|
|
|
|
// P ⸭ ⊥ = ⊥
|
2021-04-19 15:02:59 -07:00
|
|
|
|
rhs.0.and_then(|q| {
|
2021-08-12 13:33:19 -07:00
|
|
|
|
// 0 ⸭ 0 = ⊥
|
|
|
|
|
// 0 ⸭ P = ⊥
|
|
|
|
|
// P ⸭ 0 = ⊥
|
|
|
|
|
// (x, y) ⸭ (x', y') = ⊥ if x == x'
|
|
|
|
|
// (x, y) ⸭ (x', y') = (x, y) + (x', y') if x != x'
|
2021-04-21 16:59:55 -07:00
|
|
|
|
CtOption::new(
|
|
|
|
|
p + q,
|
|
|
|
|
!(p.is_identity() | q.is_identity() | p.ct_eq(&q) | p.ct_eq(&-q)),
|
|
|
|
|
)
|
2021-04-19 15:02:59 -07:00
|
|
|
|
})
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-12 07:43:19 -07:00
|
|
|
|
impl Add<pallas::Affine> for IncompletePoint {
|
|
|
|
|
type Output = IncompletePoint;
|
|
|
|
|
|
|
|
|
|
/// Specialisation of incomplete addition for mixed addition.
|
2021-08-12 13:32:14 -07:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-08-12 07:43:19 -07:00
|
|
|
|
fn add(self, rhs: pallas::Affine) -> Self::Output {
|
2021-08-12 13:33:19 -07:00
|
|
|
|
// ⊥ ⸭ ⊥ = ⊥
|
|
|
|
|
// ⊥ ⸭ P = ⊥
|
2021-08-12 07:43:19 -07:00
|
|
|
|
IncompletePoint(self.0.and_then(|p| {
|
2021-08-12 13:33:19 -07:00
|
|
|
|
// P ⸭ ⊥ = ⊥ is satisfied by definition.
|
2021-08-12 07:43:19 -07:00
|
|
|
|
let q = rhs.to_curve();
|
|
|
|
|
|
2021-08-12 13:33:19 -07:00
|
|
|
|
// 0 ⸭ 0 = ⊥
|
|
|
|
|
// 0 ⸭ P = ⊥
|
|
|
|
|
// P ⸭ 0 = ⊥
|
|
|
|
|
// (x, y) ⸭ (x', y') = ⊥ if x == x'
|
|
|
|
|
// (x, y) ⸭ (x', y') = (x, y) + (x', y') if x != x'
|
2021-08-12 07:43:19 -07:00
|
|
|
|
CtOption::new(
|
|
|
|
|
// Use mixed addition for efficiency.
|
|
|
|
|
p + rhs,
|
|
|
|
|
!(p.is_identity() | q.is_identity() | p.ct_eq(&q) | p.ct_eq(&-q)),
|
|
|
|
|
)
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
}
|