pub struct SumOfSquaresProof<G: Group> { /* private fields */ }Expand description
Zero-knowledge proof that an ElGamal-encrypted value is equal to a sum of squares of one or more other ElGamal-encrypted values.
§Construction
Consider the case with a single sum element (i.e., proving that an encrypted value is a square of another encrypted value). The prover wants to prove the knowledge of scalars
r_x, x, r_z:
R_x = [r_x]G, X = [x]G + [r_x]K;
R_z = [r_z]G, Z = [x^2]G + [r_z]K,where
Gis the conventional generator of the considered prime-order groupKis a group element equivalent to the receiver’s public key(R_x, X)and(R_z, Z)are ElGamal ciphertexts of valuesxandx^2, respectively.
Observe that
r'_z := r_z - x * r_x =>
R_z = [r'_z]G + [x]R_x; Z = [x]X + [r'_z]K.and that proving the knowledge of (r_x, x, r'_z) is equivalent to the initial problem.
The new problem can be solved using a conventional sigma protocol:
- Commitment. The prover generates random scalars
e_r,e_xande_zand commits to them viaE_r = [e_r]G,E_x = [e_x]G + [e_r]K,E_rz = [e_x]R_x + [e_z]GandE_z = [e_x]X + [e_z]K. - Challenge. The verifier sends to the prover random scalar
c. - Response. The prover computes the following scalars and sends them to the verifier.
s_r = e_r + c * r_x;
s_x = e_x + c * x;
s_z = e_z + c * (r_z - x * r_x);The verification equations are
[s_r]G ?= E_r + [c]R_x;
[s_x]G + [s_r]K ?= E_x + [c]X;
[s_x]R_x + [s_z]G ?= E_rz + [c]R_z;
[s_x]X + [s_z]K ?= E_z + [c]Z.The case with multiple squares is a straightforward generalization:
e_r,E_r,e_x,E_x,s_rands_xare independently defined for each partial ciphertext in the same way as above.- Commitments
E_rzandE_zsum over[e_x]R_xand[e_x]Xfor all ciphertexts, respectively. - Response
s_zsimilarly substitutesx * r_xwith the corresponding sum.
A non-interactive version of the proof is obtained by applying Fiat–Shamir transform.
As with LogEqualityProof, it is more efficient to represent a proof as the challenge
and responses; in this case, the proof size is 2n + 2 scalars, where n is the number of
partial ciphertexts.
Implementations§
Source§impl<G: Group> SumOfSquaresProof<G>
impl<G: Group> SumOfSquaresProof<G>
Sourcepub fn new<'a, R: RngCore + CryptoRng>(
ciphertexts: impl Iterator<Item = &'a CiphertextWithValue<G>>,
sum_of_squares_ciphertext: &CiphertextWithValue<G>,
receiver: &PublicKey<G>,
transcript: &mut Transcript,
rng: &mut R,
) -> Self
pub fn new<'a, R: RngCore + CryptoRng>( ciphertexts: impl Iterator<Item = &'a CiphertextWithValue<G>>, sum_of_squares_ciphertext: &CiphertextWithValue<G>, receiver: &PublicKey<G>, transcript: &mut Transcript, rng: &mut R, ) -> Self
Creates a new proof that squares of values encrypted in ciphertexts for receiver sum up
to a value encrypted in sum_of_squares_ciphertext.
All provided ciphertexts must be encrypted for receiver; otherwise, the created proof
will not verify.
Sourcepub fn verify<'a>(
&self,
ciphertexts: impl Iterator<Item = &'a Ciphertext<G>> + Clone,
sum_of_squares_ciphertext: &Ciphertext<G>,
receiver: &PublicKey<G>,
transcript: &mut Transcript,
) -> Result<(), VerificationError>
pub fn verify<'a>( &self, ciphertexts: impl Iterator<Item = &'a Ciphertext<G>> + Clone, sum_of_squares_ciphertext: &Ciphertext<G>, receiver: &PublicKey<G>, transcript: &mut Transcript, ) -> Result<(), VerificationError>
Verifies this proof against the provided partial ciphertexts and the ciphertext of the sum of their squares. The order of partial ciphertexts must correspond to their order when creating the proof.
§Errors
Returns an error if this proof does not verify.
Trait Implementations§
Source§impl<G: Clone + Group> Clone for SumOfSquaresProof<G>
impl<G: Clone + Group> Clone for SumOfSquaresProof<G>
Source§fn clone(&self) -> SumOfSquaresProof<G>
fn clone(&self) -> SumOfSquaresProof<G>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<'de, G: Group> Deserialize<'de> for SumOfSquaresProof<G>
impl<'de, G: Group> Deserialize<'de> for SumOfSquaresProof<G>
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>,
Auto Trait Implementations§
impl<G> Freeze for SumOfSquaresProof<G>
impl<G> RefUnwindSafe for SumOfSquaresProof<G>
impl<G> Send for SumOfSquaresProof<G>
impl<G> Sync for SumOfSquaresProof<G>
impl<G> Unpin for SumOfSquaresProof<G>
impl<G> UnwindSafe for SumOfSquaresProof<G>
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit)