pub struct SsaPartCommitment<S: PixSpec, P = <S as PixSpec>::Pseudonym> {
pub(crate) spi: SsaPolynomialId<P>,
pub(crate) constant_term: PixGroup<S>,
}Expand description
Commitment to the constant term of the polynomial with the given SsaPolynomialId.
§Why only the constant term
This used to be a full Feldman verifier — a commitment to every coefficient — so that each
individual share could be checked the moment it arrived. Classic VSS needs that, because its
shares sit with mutually distrusting parties that reconstruct later. PIX has exactly one
shareholder: the Exit holds every share, reconstructs locally, is the whole quorum, and
consumes only the recovered constant term. Checking a₀·G == C₀ once, on the reconstructed
part, is therefore deterministic and exact for the property actually relied upon — and costs
one scalar multiplication per polynomial instead of threshold per share.
What the per-coefficient commitments did buy was fault isolation: one bad share could be
rejected on arrival and its slot refilled from the surplus. That is given up. A share that
fails to reconstruct implies a dishonest or broken Entry — it travels inside a
Sphinx-authenticated SURB, and its decryption key is fixed by the very acknowledgement
challenge it is filed under, so there is no benign path to a corrupt one — and such an Entry
has already funded the deposit it thereby forfeits. The price paid is detection latency:
a dishonest Entry is caught on the threshold-th share of a polynomial rather than the first.
surplus_shares still absorbs lost shares, since
reconstruction starts at the first threshold distinct shares that arrive.
Fields§
§spi: SsaPolynomialId<P>§constant_term: PixGroup<S>Implementations§
Source§impl<S: PixSpec> SsaPartCommitment<S, S::Pseudonym>
impl<S: PixSpec> SsaPartCommitment<S, S::Pseudonym>
Sourcepub fn from_decoded_commitment(
spi: SsaPolynomialId<S::Pseudonym>,
constant_term: PixGroup<S>,
) -> Self
pub fn from_decoded_commitment( spi: SsaPolynomialId<S::Pseudonym>, constant_term: PixGroup<S>, ) -> Self
Creates a commitment from an already decoded and subgroup-checked group element.
The only decode is decode_commitment, performed once when the
commitment arrives on the wire. Decompression requires a modular square root and is the
dominant per-commitment cost, so nothing here decodes a second time.
Sourcepub fn spi(&self) -> &SsaPolynomialId<S::Pseudonym>
pub fn spi(&self) -> &SsaPolynomialId<S::Pseudonym>
Returns the SsaPolynomialId of the polynomial this commitment belongs to.
Sourcepub fn constant_term(&self) -> &PixGroup<S>
pub fn constant_term(&self) -> &PixGroup<S>
Returns the commitment to the constant term of the polynomial.
Sourcepub fn verify_reconstructed(&self, secret: &PixScalar<S>) -> bool
pub fn verify_reconstructed(&self, secret: &PixScalar<S>) -> bool
Checks a reconstructed constant term against this commitment.
This is the entire verification the Exit performs on a polynomial, and it happens once,
after threshold shares have been interpolated. A mismatch means at least one of those
shares did not come from the committed polynomial; it does not say which.
Sourcepub fn decode_commitment(
commitment: &PixGroupRepr<S>,
) -> Result<PixGroup<S>, S::Pseudonym>
pub fn decode_commitment( commitment: &PixGroupRepr<S>, ) -> Result<PixGroup<S>, S::Pseudonym>
Decodes a single serialized coefficient commitment into a group element.
Rejects bytes that do not decode, and points outside the prime-order subgroup: Baby JubJub has cofactor 8, so small-order points can pass the plain on-curve check.
No value-based filtering is applied — a coefficient commitment equal to the generator validly represents scalar coefficient 1 and must be preserved.
Trait Implementations§
Source§impl<S: Clone + PixSpec, P: Clone> Clone for SsaPartCommitment<S, P>
impl<S: Clone + PixSpec, P: Clone> Clone for SsaPartCommitment<S, P>
Source§fn clone(&self) -> SsaPartCommitment<S, P>
fn clone(&self) -> SsaPartCommitment<S, P>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<'de, S: PixSpec, P> Deserialize<'de> for SsaPartCommitment<S, P>where
P: Deserialize<'de>,
impl<'de, S: PixSpec, P> Deserialize<'de> for SsaPartCommitment<S, P>where
P: Deserialize<'de>,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl<S: Eq + PixSpec, P: Eq> Eq for SsaPartCommitment<S, P>
impl<S: PartialEq + PixSpec, P: PartialEq> StructuralPartialEq for SsaPartCommitment<S, P>
Auto Trait Implementations§
impl<S, P> Freeze for SsaPartCommitment<S, P>
impl<S, P> RefUnwindSafe for SsaPartCommitment<S, P>
impl<S, P> Send for SsaPartCommitment<S, P>where
P: Send,
impl<S, P> Sync for SsaPartCommitment<S, P>where
P: Sync,
impl<S, P> Unpin for SsaPartCommitment<S, P>
impl<S, P> UnsafeUnpin for SsaPartCommitment<S, P>
impl<S, P> UnwindSafe for SsaPartCommitment<S, P>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<'de, T> BorrowedRpcObject<'de> for Twhere
T: RpcBorrow<'de> + RpcSend,
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more