Skip to content

Correctiones #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 60 additions & 58 deletions report/src/sections/04-Approach.tex
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,26 @@ \subsection{Springproofs}\label{sec:approach-springproofs}
In a general~\gls{ipa}, Curdleproofs included, if the size of the vectors were not a power of two, the argument would not recurse down to size 1, as they work by halving the vectors every recursive round.


The core concept of the Springproofs scheme function is to split the vectors into sets, $T$ and $S$, before each recursive round of the protocol.
Then, the fold for that round is only done on one of the two sets,~$T$, before the other set,~$S$, is appended again at the end of the recursive round.
The core concept of the Springproofs scheme function is to split the vectors into sets, $\mathbf{\mathcal{T}}$ and $\mathbf{\mathcal{S}}$, before each recursive round of the protocol.
Then, the fold for that round is only done on one of the two sets,~$\mathbf{\mathcal{T}}$, before the other set,~$\mathbf{\mathcal{S}}$, is appended again at the end of the recursive round.

Springproofs present different scheme functions and prove some of them to be optimal.
One of these optimal functions is an optimized version of their \textit{pre-compression method}, which splits the vectors as seen in~\autoref{lst:schemefunc}.
The computation is for finding the set,~$T$.
The computation is for finding the set,~$\mathbf{\mathcal{T}}$.

\begin{figure}[!htb]
\begin{lstlisting}[language=Python,mathescape=true,label={lst:schemefunc},numbers=right,caption={Scheme function \textbf{\textit{f}} used in CAAUrdleproofs},captionpos=b,frame=single]
input: $n$, where $n>0$

$\{n\}\gets n$
$\mathbf{n}\gets \{1..n\}$
$N\gets 2^{\lceil\log n\rceil-1}$
$i_h \gets \lfloor (2N-n)/2\rfloor+1$
$i_t=\lfloor n/2\rfloor$
if $n\neq N$: #Not power of 2
$\{T\}\gets(i_h:i_t)\cup(N+1:n)$
$\mathbf{\mathcal{T}}\gets\{i_h:i_t\}\cup\{N+1:n\}$
else if $n=N$: #Power of 2
$\{T\}\gets(1:n)$ #Meaning S is empty
$\{S\}\gets\{n\}-\{T\}$
$\mathbf{\mathcal{T}}\gets\{1:n\}$ #Meaning S is empty
$\mathbf{\mathcal{S}}\gets\mathbf{n}-\mathbf{\mathcal{T}}$
\end{lstlisting}
\label{fig:schemefunc}
\end{figure}
Expand Down Expand Up @@ -65,8 +65,9 @@ \subsubsection*{Prover computation}
The construction can be seen in~\autoref{lst:ipa-prover}.

\begin{figure}[!htb]
\begin{lstlisting}[language=Python,mathescape=true,label={lst:ipa-prover},numbers=left,caption={Prover computation for CAAU-IPA in CAAUrdleproofs},captionpos=b,frame=single]
\begin{lstlisting}[language=Python,mathescape=true,label={lst:ipa-prover},numbers=right,caption={Prover computation for CAAU-IPA in CAAUrdleproofs},captionpos=b,frame=single]
$\textbf{Step 1:}$ #Setup phase
$(\mathbf{c},\mathbf{d},z,C,D)\gets$parse$(input)$
$(\textbf{G},\textbf{G}',H)\gets$parse$(crs_{dl_{inner}})$
$\textbf{r}_C,\textbf{r}_D\overset{\$}{\leftarrow}\mathbb{F}^n$ #Vector blinders
where $(\textbf{r}_C\times \textbf{d} + \textbf{r}_D\times \textbf{c})=0\text{ and }\textbf{r}_C\times \textbf{r}_D=0$
Expand All @@ -79,12 +80,12 @@ \subsubsection*{Prover computation}
$\textbf{Step 2:}$ #Recursive protocol
$m\gets \lceil \log n\rceil$
while $1\leq j\leq m:$
$T,S\gets \textbf{\textit{f(}}n\textbf{\textit{)}}$ #Scheme function
$n\gets \frac{|T|}{2}$
$\textbf{c}\gets\textbf{c}_T$, $\textbf{cS}\gets\textbf{c}_S$ #Vector splitting
$\textbf{d}\gets\textbf{d}_T$, $\textbf{dS}\gets\textbf{d}_S$
$\textbf{G}\gets\textbf{G}_T$, $\textbf{GS}\gets\textbf{G}_S$
$\textbf{G}'\gets\textbf{G}'_T$, $\textbf{GS}'\gets\textbf{G}'_T$
$\mathbf{\mathcal{T}},\mathbf{\mathcal{S}}\gets \textbf{\textit{f(}}n\textbf{\textit{)}}$ #Scheme function
$n\gets \frac{|\mathbf{\mathcal{T}}|}{2}$
$\textbf{c}\gets\textbf{c}_\mathbf{\mathcal{T}}$, $\textbf{cS}\gets\textbf{c}_\mathbf{\mathcal{S}}$ #Vector splitting
$\textbf{d}\gets\textbf{d}_\mathbf{\mathcal{T}}$, $\textbf{dS}\gets\textbf{d}_\mathbf{\mathcal{S}}$
$\textbf{G}\gets\textbf{G}_\mathbf{\mathcal{T}}$, $\textbf{GS}\gets\textbf{G}_\mathbf{\mathcal{S}}$
$\textbf{G}'\gets\textbf{G}'_\mathbf{\mathcal{T}}$, $\textbf{GS}'\gets\textbf{G}'_\mathbf{\mathcal{S}}$
$L_{C,j}\gets\textbf{c}_{[:n]}\times\textbf{G}_{[n:]}+(\textbf{c}_{[:n]}\times\textbf{d}_{[n:]})H$ #Cross-comm
$L_{D,j}\gets\textbf{d}_{[n:]}\times\textbf{G}'_{[:n]}$
$R_{C,j}\gets\textbf{c}_{[n:]}\times\textbf{G}_{[:n]}+(\textbf{c}_{[n:]}\times\textbf{d}_{[:n]})H$
Expand All @@ -106,37 +107,38 @@ \subsubsection*{Prover computation}
\end{figure}
First, we have step 1, which is the setup phase.
It is implemented the same way as in Curdleproofs.
In line 2, the prover gets the cryptographic generators, $\mathbf{G}$, $\mathbf{G}'$ and $H$, which are going to be used for commitment constructions.
To ensure zero-knowledge, two blinding vectors for each commitment are constructed on lines 3--4.
From the prover input, line 2, we obtain the vectors $\mathbf{c}$ and $\mathbf{d}$, whose inner product we aim to prove is equal to $z$, as well as the commitments $C$ and $D$.
In line 3, the prover gets the cryptographic generators, $\mathbf{G}$, $\mathbf{G}'$ and $H$, which are going to be used for commitment constructions.
To ensure zero-knowledge, two blinding vectors for each commitment are constructed on lines 4--5.
These are also given the properties, $(\mathbf{r}_C\times \mathbf{d}+\mathbf{r}_D\times \mathbf{c})=0$~and~ $\mathbf{r}_C\times\mathbf{r}_D=0$, ensuring the completeness of the protocol.

After this, commitments to the blinding vectors are constructed as $B_C$ and $B_D$ on lines 5--6.
After this, commitments to the blinding vectors are constructed as $B_C$ and $B_D$ on lines 6--7.
These will eventually be used for verification by the verifier.

From the public input, hash values $\alpha,\beta$ are then computed on line 7.
From the public input, hash values $\alpha,\beta$ are then computed on line 8.
These are used to ensure the soundness of the protocol.

On lines 8--10, the two vectors are then blinded and multiplied by the $\alpha$ hash to ensure the zero-knowledge and soundness, as well as $H=\beta H$.
On lines 9--11, the two vectors are then blinded and multiplied by the $\alpha$ hash to ensure the zero-knowledge and soundness, as well as $H=\beta H$.


Now, the recursive proof construction, and step 2, begins.
As explained, at the start of the recursive round, line 13, we find the split of the vectors on line 14, with $f(n)$ being the scheme function from~\autoref{lst:schemefunc}.
Then, on line 15, we find half the length of the $T$ set, as it is the set we are doing the recursive folding round on.
Equally, on lines 16--19, we split our witness vectors and the group vectors using $T$ and $S$.
As explained, at the start of the recursive round, line 14, we find the split of the vectors on line 15, with $f(n)$ being the scheme function from~\autoref{lst:schemefunc}.
Then, on line 16, we find half the length of the $\mathbf{\mathcal{T}}$ set, as it is the set we are doing the recursive folding round on.
Equally, on lines 17--20, we split our witness vectors and the group vectors using $\mathbf{\mathcal{T}}$ and $\mathbf{\mathcal{S}}$.

After this, the prover constructs cross-commitment elements on lines 20--23 that are computed on the $T$ set.
These are added to the proof on line 24, which eventually is available to the verifier.
They are also used to construct a hash value,~$\gamma_j$, in the next step on line 25.
After this, the prover constructs cross-commitment elements on lines 21--24 that are computed on the $\mathbf{\mathcal{T}}$ set.
These are added to the proof on line 25, which eventually is available to the verifier.
They are also used to construct a hash value,~$\gamma_j$, in the next step on line 26.

This value is used on lines 26--29 for completing the folding of $\mathbf{c},\mathbf{d},\mathbf{G},\mathbf{G'}$.
We do the fold as in the original Curdleproofs protocol while also appending the elements of $S$ back onto the vectors.
This value is used on lines 27--30 for completing the folding of $\mathbf{c},\mathbf{d},\mathbf{G},\mathbf{G'}$.
We do the fold as in the original Curdleproofs protocol while also appending the elements of $\mathbf{\mathcal{S}}$ back onto the vectors.
The figure shows a concatenation, but it is important to know that the vectors are appended together as shown in~\autoref{fig:fold}(b).

At the end of the recursive round, on line 30,~$n$ is updated to the length of the concatenated vectors before starting a new round.
At the end of the recursive round, on line 31,~$n$ is updated to the length of the concatenated vectors before starting a new round.

The result of this is a proof,~$\mathbf{\pi}$, constructed in $\lceil \log n \rceil$ rounds, but with the proof size being smaller than if the shuffle size was a power of 2.

In step 3, lines 31--35, the folded vectors of size 1 are added to the proof as values as well as the commitments to the blinding values,~$B_C$ and~$B_D$.
In step 3, lines 32--36, the folded vectors of size 1 are added to the proof as values as well as the commitments to the blinding values,~$B_C$ and~$B_D$.
The proof, folded vectors, and updated commitment are saved for the verifier to use for verification.


Expand All @@ -160,10 +162,10 @@ \subsubsection*{Verifier computation}
$\textbf{Step 2:}$ #Recursive round
$m\gets \lceil\log n\rceil$
for $1\leq j\leq m$
$T,S\gets \textbf{\textit{f(}}n\textbf{\textit{)}}$ #Scheme function
$n\gets \frac{|T|}{2}$
$\textbf{G}=\textbf{G}_T$, $\textbf{GS}=\textbf{G}_S$ #Vector splitting
$\textbf{G}'=\textbf{G}'_T$, $\textbf{GS}'=\textbf{G}'_T$
$\mathbf{\mathcal{T}},\mathbf{\mathcal{S}}\gets \textbf{\textit{f(}}n\textbf{\textit{)}}$ #Scheme function
$n\gets \frac{|\mathbf{\mathcal{T}}|}{2}$
$\textbf{G}=\textbf{G}_\mathbf{\mathcal{T}}$, $\textbf{GS}=\textbf{G}_\mathbf{\mathcal{S}}$ #Vector splitting
$\textbf{G}'=\textbf{G}'_\mathbf{\mathcal{T}}$, $\textbf{GS}'=\textbf{G}'_\mathbf{\mathcal{S}}$
$(L_{C,j},L_{D,j},R_{C,j},R_{D,j})\gets$parse$(\pi_j)$ #Proof elem
$\gamma_j\gets$Hash$(\pi_j)$ #Folding challenges
$C\gets\gamma_j L_{C,j}+C+\gamma_j^{-1}R_{C,j}$ #Update comms
Expand All @@ -175,7 +177,7 @@ \subsubsection*{Verifier computation}
$\textbf{Step 3:}$ #Final check
Check $C=c\times G_1+cdH$ #Initial ?= Folded
Check $D=d\times G'_1$
return 1 $\text{if both checks pass, else}$ return 0
return 1 $\text{if both checks pass, otherwise}$ return 0
\end{lstlisting}
\label{fig:ipa-verifier}
\end{figure}
Expand All @@ -194,8 +196,8 @@ \subsubsection*{Verifier computation}
Those modifications mean that the commitments~$C$ and~$D$ need to be commitments to the modified witnesses instead.

The setup phase is now complete, and the verifier then executes the recursive protocol, as shown in step 2.
First, the vectors are divided into two sets,~$T$ and $S$, on line 13, as in~\autoref{lst:ipa-prover}.
After this, the group vectors are in lines 14--16 split according to those sets, along with updating~$n$ to be half the size of~$T$.
First, the vectors are divided into two sets,~$\mathbf{\mathcal{T}}$ and $\mathbf{\mathcal{S}}$, on line 13, as in~\autoref{lst:ipa-prover}.
After this, the group vectors are in lines 14--16 split according to those sets, along with updating~$n$ to be half the size of~$\mathbf{\mathcal{T}}$.

The verifier then, on line 17, retrieves from the proof the cross-product commitment update values for the given round,~$L_{C,j},L_{D,j},R_{C,j},R_{D,j}$.
These are used for constructing a new commitment, lines 19--20, according to the fold made at round $i$.
Expand Down Expand Up @@ -233,25 +235,25 @@ \subsection{Shuffle security}\label{subsec:approach-shuffle-security}
\rule{\linewidth}{0.4pt}

\noindent
\textbf{For} $t \in [T]$ \textbf{:}
\textbf{For} $q \in [Q]$ \textbf{:}
\begin{itemize}
\item[$S_t$] picks random $\{i_1, \ldots, i_\ell\} \subset [n]$
\item[$S_t$] computes $(\tilde{c}_{i_1}, \ldots, \tilde{c}_{i_\ell}) \leftarrow \text{Shuffle}(c_{i_1}, \ldots, c_{i_\ell})$
\item[$S_t$] publishes $(\tilde{c}_{i_1}, \ldots, \tilde{c}_{i_\ell})$
\item[$S_q$] picks random $\{i_1, \ldots, i_\ell\} \subset [n]$
\item[$S_q$] computes $(\tilde{c}_{i_1}, \ldots, \tilde{c}_{i_\ell}) \leftarrow \text{Shuffle}(c_{i_1}, \ldots, c_{i_\ell})$
\item[$S_q$] publishes $(\tilde{c}_{i_1}, \ldots, \tilde{c}_{i_\ell})$
\end{itemize}
\end{framed}
\caption{Distributed shuffling protocol. Source:~\cite{cryptoeprint:2022/560}}
\label{fig:shuffle}
\end{figure}

Here the set $(c_1, \ldots, c_n)$ is a set of ciphertexts that are shuffled over $T$ slots.
In each slot $t$, a subset of the ciphertexts ${i_1, \ldots, i_\ell}$ is chosen randomly, shuffled and added back to the list of ciphertexts.
Here the set $(c_1, \ldots, c_n)$ is a set of ciphertexts that are shuffled over $Q$ slots.
In each slot $q$, a subset of the ciphertexts ${i_1, \ldots, i_\ell}$ is chosen randomly, shuffled and added back to the list of ciphertexts.
The shuffler then re-encrypts the ciphertexts and publishes them.
This process is repeated for $T$ slots, and the shuffle is complete.
During the $T$ shuffles, some shuffles may be adversarial.
This process is repeated for $Q$ slots, and the shuffle is complete.
During the $Q$ shuffles, some shuffles may be adversarial.
An adversary can choose to do anything with its shuffle, including not shuffling.
Hence, an adversarial shuffle can be seen as no shuffling being done.
Therefore, the number of honest shuffles that happen during the shuffle process is $T_H = T - \beta$, where $\beta$ is the number of adversarial shuffles.
Therefore, the number of honest shuffles that happen during the shuffle process is $Q_H = Q - \beta$, where $\beta$ is the number of adversarial shuffles.

The adversary can also track ciphertexts.
For instance, if the adversary owns some of the ciphertexts.
Expand All @@ -265,12 +267,12 @@ \subsection{Shuffle security}\label{subsec:approach-shuffle-security}
So, if a shuffle contains many ciphertexts with a larger-than-average chance of containing a specific ciphertext, then that would imply that there is a higher chance of that ciphertext being in that slot.

It is theoretically possible to find a number of shuffles, given a shuffle size and a number of adversarial shufflers, which guarantees that the shuffle is secure.
For any $0 < \delta < 1/3$, if $T \geq 20 n / \ell \ln(n/\delta) + \beta $ and $ \ell \geq 256 \ln^2(n/\delta)(1 - \alpha/n)^{-2}$.
If $T$ and $\ell$ are chosen such that the above two conditions are met, then the protocol is an $(\epsilon , \delta)$-secure $(T,n,\ell)$-shuffle in the presence of a $(\alpha, \beta)$-adversary where $\epsilon = 2/(n-\alpha)$.
For any $0 < \delta < 1/3$, if $Q \geq 20 n / \ell \ln(n/\delta) + \beta $ and $ \ell \geq 256 \ln^2(n/\delta)(1 - \alpha/n)^{-2}$.
If $Q$ and $\ell$ are chosen such that the above two conditions are met, then the protocol is an $(\epsilon , \delta)$-secure $(Q,n,\ell)$-shuffle in the presence of a $(\alpha, \beta)$-adversary where $\epsilon = 2/(n-\alpha)$.

This formula is the lowest theoretically proven bound for $T$ and $\ell$.
This formula is the lowest theoretically proven bound for $Q$ and $\ell$.
Plotting numbers relevant to Whisk will show that this theoretical bound is too large to use for argumentation of security.
It is, however, possible to find lower secure values for $T$ and $\ell$, but this has to be done experimentally.
It is, however, possible to find lower secure values for $Q$ and $\ell$, but this has to be done experimentally.


\subsection{Implementation}\label{subsec:approach-implementation}
Expand Down Expand Up @@ -309,25 +311,25 @@ \subsubsection{CAAUrdleproofs}
$\textbf{Step 2:}$ #Recursive phase
$m\gets \lceil\log n\rceil$
for $1\leq j\leq m$
$T,S\gets \textbf{\textit{f(}}n\textbf{\textit{)}}$ #Scheme function
$n\gets \frac{|T|}{2}$
$\mathbf{\mathcal{T}},\mathbf{\mathcal{S}}\gets \textbf{\textit{f(}}n\textbf{\textit{)}}$ #Scheme function
$n\gets \frac{|\mathbf{\mathcal{T}}|}{2}$
$(L_{C,j},L_{D,j},R_{C,j},R_{D,j})\gets$parse$(\pi_j)$ #Proof elem
$\gamma_j\gets$Hash$(\pi_j)$ #Folding challenges
$n\gets n+\text{len}(S)$
$n\gets n+|\mathbf{\mathcal{S}}|$

$\textbf{Step 3:}$ # Accumulated checking phase
$\mathbf{CP}\text{: }\mathbf{\gamma}\gets(\gamma_m,...,\gamma_1)$ #Construction difference
$\mathbf{CAAUP}\text{: }\mathbf{\gamma}\gets(\gamma_1,...,\gamma_m)$
$\mathbf{CP}\text{: }\mathbf{\delta}\gets(\gamma_m,...,\gamma_1)$ #Construction difference
$\mathbf{CAAUP}\text{: }\mathbf{\delta}\gets(\gamma_1,...,\gamma_m)$
$\textit{Compute }\mathbf{s}\textit{: see below for difference}$

AccumulateCheck$(\mathbf{\gamma}\times\mathbf{L}_C+(B_C+\alpha C+(\alpha^2z)H)$
$+\mathbf{\gamma}^{-1}\times\mathbf{R}_C\stackrel{?}{=}(c\mathbf{s}\| cd\beta)\times(\mathbf{G}\| H))$
AccumulateCheck$(\mathbf{\gamma}\times\mathbf{L}_D+(B_D+\alpha D)$
$+\mathbf{\gamma}^{-1}\times\mathbf{R}_D\stackrel{?}{=}d(\mathbf{s'}\circ\mathbf{u})\times\mathbf{G})$
$\text{return 1}$
return 1 $\text{if checks pass, otherwise}$ return 0

$\textbf{s-step Curdleproofs:}$
for $1\leq j\leq n$: Simulate halving each round
for $1\leq j\leq n$: #Simulate halving each round
$s_i=\sum_{j=1}^m\delta_j^{b_{i,j}}\text{, }b_{i,j}\in\{0,1\}\text{ s.t. }i=\sum_{j=1}^mb_{i,j}2^j$
$s'_i=\sum_{j=1}^m\delta_j^{-b_{i,j}}$
$\textbf{s-step CAAUrdleproofs:}$
Expand Down Expand Up @@ -364,9 +366,9 @@ \subsubsection{CAAUrdleproofs}

In Curdleproofs, both the~\gls{sameperm} and~\gls{samemsm} proof are recursive~\glspl{ipa}.
So, the modifications and optimization used on the~\gls{sameperm} argument are also used on the~\gls{samemsm} argument.
The modifications include the split into set $T$ and $S$ before recursion and the construction of the bit matrix,~$b_{i,j}$, to keep track of multiplications on individual elements.
The modifications include the split into set $\mathbf{\mathcal{T}}$ and $\mathbf{\mathcal{S}}$ before recursion and the construction of the bit matrix,~$b_{i,j}$, to keep track of multiplications on individual elements.

It is also worth noting that the concatenation of $T$ and $S$ in the recursive phase, lines 26--29 in~\autoref{lst:ipa-prover}, is handled effectively in the code.
It is also worth noting that the concatenation of $\mathbf{\mathcal{T}}$ and $\mathbf{\mathcal{S}}$ in the recursive phase, lines 26--29 in~\autoref{lst:ipa-prover}, is handled effectively in the code.
Instead of concatenating, the computation uses pointers to the original vector, so it never practically concatenates.

The code also uses the fact that the used scheme function will always end up with vectors being a power of two after the first round.
Expand Down
Loading
Loading