mirror of
https://github.com/arnaucube/math.git
synced 2026-01-10 16:01:31 +01:00
paper-notes: Add modified IPA (from Halo)
This commit is contained in:
4
ipa.sage
4
ipa.sage
@@ -6,7 +6,7 @@
|
||||
|
||||
# IPA_bulletproofs implements the IPA version from the Bulletproofs paper: https://eprint.iacr.org/2017/1066.pdf
|
||||
# https://doc-internal.dalek.rs/bulletproofs/notes/inner_product_proof/index.html
|
||||
class IPA_bulletproofs(object):
|
||||
class IPA_bulletproofs:
|
||||
def __init__(self, F, E, g, d):
|
||||
self.g = g
|
||||
self.F = F
|
||||
@@ -89,7 +89,7 @@ class IPA_bulletproofs(object):
|
||||
return C == D
|
||||
|
||||
# IPA_halo implements the modified IPA from the Halo paper: https://eprint.iacr.org/2019/1021.pdf
|
||||
class IPA_halo(object):
|
||||
class IPA_halo:
|
||||
def __init__(self, F, E, g, d):
|
||||
self.g = g
|
||||
self.F = F
|
||||
|
||||
@@ -31,3 +31,11 @@
|
||||
note = {\url{https://eth2book.info/altair/part2/building_blocks/signatures}},
|
||||
url = {https://eth2book.info/altair/part2/building_blocks/signatures}
|
||||
}
|
||||
@misc{cryptoeprint:2019/1021,
|
||||
author = {Sean Bowe and Jack Grigg and Daira Hopwood},
|
||||
title = {Recursive Proof Composition without a Trusted Setup},
|
||||
howpublished = {Cryptology ePrint Archive, Paper 2019/1021},
|
||||
year = {2019},
|
||||
note = {\url{https://eprint.iacr.org/2019/1021}},
|
||||
url = {https://eprint.iacr.org/2019/1021}
|
||||
}
|
||||
|
||||
BIN
paper-notes.pdf
BIN
paper-notes.pdf
Binary file not shown.
103
paper-notes.tex
103
paper-notes.tex
@@ -12,6 +12,7 @@
|
||||
linkcolor=black,
|
||||
urlcolor=blue
|
||||
}
|
||||
\usepackage{xcolor}
|
||||
|
||||
% prevent warnings of underfull \hbox:
|
||||
\usepackage{etoolbox}
|
||||
@@ -224,17 +225,115 @@ Identical to verification of a normal signature as long as we use the same corre
|
||||
$$e(g_1, \sigma_{aggr})==e(pk_{aggr}, H(m))$$
|
||||
|
||||
Unfold:
|
||||
$$e(pk_{aggr}, H(m))=e(pk_1 + pk_2 + \ldots + pk_n, H(m))=$$
|
||||
$$\fbox{e(pk_{aggr}, H(m))}= e(pk_1 + pk_2 + \ldots + pk_n, H(m)) =$$
|
||||
$$=e([sk_1] \cdot g_1 + [sk_2] \cdot g_1 + \ldots + [sk_n] \cdot g_1, H(m))=$$
|
||||
$$=e([sk_1 + sk_2 + \ldots + sk_n] \cdot g_1, H(m))=$$
|
||||
$$=e(g_1, H(m))^{(sk_1 + sk_2 + \ldots + sk_n)}=$$
|
||||
$$=e(g_1, [sk_1 + sk_2 + \ldots + sk_n] \cdot H(m))=$$
|
||||
$$=e(g_1, [sk_1] \cdot H(m) + [sk_2] \cdot H(m) + \ldots + [sk_n] \cdot H(m))=$$
|
||||
$$=e(g_1, \sigma_1 + \sigma_2 + \ldots + \sigma_n)=e(g_1, \sigma_{aggr})$$
|
||||
$$=e(g_1, \sigma_1 + \sigma_2 + \ldots + \sigma_n)= \fbox{e(g_1, \sigma_{aggr})}$$
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\section{modified IPA (from Halo)}
|
||||
Notes taken while reading about the modified Inner Product Argument (IPA) from the Halo paper \cite{cryptoeprint:2019/1021}.
|
||||
|
||||
\subsection{Notation}
|
||||
\begin{description}
|
||||
\item[Scalar mul] $[a]G$, where $a$ is a scalar and $G \in \mathbb{G}$
|
||||
\item[Inner product] $<\overrightarrow{a}, \overrightarrow{b}> = a_0 b_0 + a_1 b_1 + \ldots + a_{n-1} b_{n-1}$
|
||||
\item[Multiscalar mul] $<\overrightarrow{a}, \overrightarrow{b}> = [a_0] G_0 + [a_1] G_1 + \ldots [a_{n-1}] G_{n-1}$
|
||||
\end{description}
|
||||
|
||||
|
||||
\subsection{Transparent setup}
|
||||
$\overrightarrow{G} \in^r \mathbb{G}^d$, $H \in^r \mathbb{G}$
|
||||
|
||||
Prover wants to commit to $p(x)=a_0$
|
||||
\subsection{Protocol}
|
||||
Prover:
|
||||
$$P=<\overrightarrow{a}, \overrightarrow{G}> + [r]H$$
|
||||
$$v=<\overrightarrow{a}, \{1, x, x^2, \ldots, x^{d-1} \} >$$
|
||||
|
||||
where $\{1, x, x^2, \ldots, x^{d-1} \} = \overrightarrow{b}$.
|
||||
|
||||
We can see that computing $v$ is the equivalent to evaluating $p(x)$ at $x$ ($p(x)=v$).
|
||||
|
||||
We will prove:
|
||||
\begin{enumerate}[i.]
|
||||
\item polynomial $p(X) = \sum a_i X^i$\\
|
||||
$p(x) = v$ (that $p(X)$ evaluates $x$ to $v$).
|
||||
\item $deg(p(X)) \leq d-1$
|
||||
\end{enumerate}
|
||||
|
||||
|
||||
Both parties know $P$, point $x$ and claimed evaluation $v$. For $U \in^r \mathbb{G}$,
|
||||
|
||||
$$P' = P + [v] U = <\overrightarrow{a}, G> + [r]H + [v] U$$
|
||||
|
||||
Now, for $k$ rounds ($d=2^k$, from $j=k$ to $j=1$):
|
||||
\begin{itemize}
|
||||
\item random blinding factors: $l_j, r_j \in \mathbb{F}_p$
|
||||
\item
|
||||
$$L_j = < \overrightarrow{a}_{lo}, \overrightarrow{G}_{hi}> + [l_j] H + [< \overrightarrow{a}_{lo}, \overrightarrow{b}_{hi}>] U$$
|
||||
$$L_j = < \overrightarrow{a}_{lo}, \overrightarrow{G}_{hi}> + [l_j] H + [< \overrightarrow{a}_{lo}, \overrightarrow{b}_{hi}>] U$$
|
||||
\item Verifier sends random challenge $u_j \in \mathbb{I}$
|
||||
\item Prover computes the halved vectors for next round:
|
||||
$$\overrightarrow{a} \leftarrow \overrightarrow{a}_{hi} \cdot u_j^{-1} + \overrightarrow{a}_{lo} \cdot u_j$$
|
||||
$$\overrightarrow{b} \leftarrow \overrightarrow{b}_{lo} \cdot u_j^{-1} + \overrightarrow{b}_{hi} \cdot u_j$$
|
||||
$$\overrightarrow{G} \leftarrow \overrightarrow{G}_{lo} \cdot u_j^{-1} + \overrightarrow{G}_{hi} \cdot u_j$$
|
||||
\end{itemize}
|
||||
|
||||
After final round, $\overrightarrow{a}, \overrightarrow{b}, \overrightarrow{G}$ are each of length 1.
|
||||
|
||||
Verifier can compute
|
||||
$$G = \overrightarrow{G}_0 = < \overrightarrow{s}, \overrightarrow{G} >$$
|
||||
and $$b = \overrightarrow{b}_0 = < \overrightarrow{s}, \overrightarrow{b} >$$
|
||||
where $\overrightarrow{s}$ is the binary counting structure:
|
||||
|
||||
\begin{align*}
|
||||
&s = (u_1^{-1} ~ u_2^{-1} \cdots ~u_k^{-1},\\
|
||||
&~~~~~~u_1 ~~~ u_2^{-1} ~\cdots ~u_k^{-1},\\
|
||||
&~~~~~~u_1^{-1} ~~ u_2 ~~\cdots ~u_k^{-1},\\
|
||||
&~~~~~~~~~~~~~~\vdots\\
|
||||
&~~~~~~u_1 ~~~~ u_2 ~~\cdots ~u_k)
|
||||
\end{align*}
|
||||
|
||||
|
||||
And verifier checks:
|
||||
$$[a]G + [r'] H + [ab] U == P' + \sum_{j=1}^k ( [u_j^2] L_j + [u_j^{-2}] R_j)$$
|
||||
|
||||
where the synthetic blinding factor $r'$ is $r' = r + \sum_{j=1}^k (l_j u_j^2 + r_j u_j^{-2})$.
|
||||
|
||||
\vspace{1cm}
|
||||
|
||||
Unfold:
|
||||
|
||||
$$
|
||||
\textcolor{brown}{[a]G} + \textcolor{cyan}{[r'] H} + \textcolor{magenta}{[ab] U}
|
||||
==
|
||||
\textcolor{blue}{P'} + \sum_{j=1}^k ( \textcolor{violet}{[u_j^2] L_j} + \textcolor{orange}{[u_j^{-2}] R_j})
|
||||
$$
|
||||
|
||||
\begin{align*}
|
||||
&Right~side = \textcolor{blue}{P'} + \sum_{j=1}^k ( \textcolor{violet}{[u_j^2] L_j} + \textcolor{orange}{[u_j^{-2}] R_j})\\
|
||||
&= \textcolor{blue}{< \overrightarrow{a}, \overrightarrow{G}> + [r] H + [v] U}\\
|
||||
&+ \sum_{j=1}^k (\\
|
||||
&\textcolor{violet}{[u_j^2] \cdot <\overrightarrow{a}_{lo}, \overrightarrow{G}_{hi}> + [l_j] H + [<\overrightarrow{a}_{lo}, \overrightarrow{b}_{hi}>] U}\\
|
||||
&\textcolor{orange}{+ [u_j^{-2}] \cdot <\overrightarrow{a}_{hi}, \overrightarrow{G}_{lo}> + [r_j] H + [<\overrightarrow{a}_{hi}, \overrightarrow{b}_{lo}>] U}
|
||||
)
|
||||
\end{align*}
|
||||
|
||||
\begin{align*}
|
||||
&Left~side = \textcolor{brown}{[a]G} + \textcolor{cyan}{[r'] H} + \textcolor{magenta}{[ab] U}\\
|
||||
& = \textcolor{brown}{< \overrightarrow{a}, \overrightarrow{G} >}\\
|
||||
&+ \textcolor{cyan}{[r + \sum_{j=1}^k (l_j \cdot u_j^2 + r_j u_j^{-2})] \cdot H}\\
|
||||
&+ \textcolor{magenta}{< \overrightarrow{a}, \overrightarrow{b} > U}
|
||||
\end{align*}
|
||||
|
||||
|
||||
\bibliography{paper-notes.bib}
|
||||
\bibliographystyle{unsrt}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ def print_ring(a):
|
||||
print(i, a[i])
|
||||
print("")
|
||||
|
||||
class Prover(object):
|
||||
class Prover:
|
||||
def __init__(self, F, g):
|
||||
self.F = F # Z_p
|
||||
self.g = g # elliptic curve generator
|
||||
|
||||
20
sigma.sage
20
sigma.sage
@@ -14,9 +14,9 @@ def generic_verify(g, X, A, c, z):
|
||||
# Sigma protocol interactive
|
||||
###
|
||||
|
||||
class Prover_interactive(object):
|
||||
class Prover_interactive:
|
||||
def __init__(self, F, g):
|
||||
self.F = F # Z_p
|
||||
self.F = F # Z_q
|
||||
self.g = g # elliptic curve generator
|
||||
|
||||
def new_key(self):
|
||||
@@ -32,7 +32,7 @@ class Prover_interactive(object):
|
||||
def gen_proof(self, c):
|
||||
return int(self.a) + int(c) * int(self.w)
|
||||
|
||||
class Verifier_interactive(object):
|
||||
class Verifier_interactive:
|
||||
def __init__(self, F, g):
|
||||
self.F = F
|
||||
self.g = g
|
||||
@@ -49,7 +49,7 @@ class Verifier_interactive(object):
|
||||
###
|
||||
# Sigma protocol non-interactive
|
||||
###
|
||||
class Prover(object):
|
||||
class Prover:
|
||||
def __init__(self, F, g):
|
||||
self.F = F # Z_p
|
||||
self.g = g # elliptic curve generator
|
||||
@@ -67,7 +67,7 @@ class Prover(object):
|
||||
return A, z
|
||||
|
||||
|
||||
class Verifier(object):
|
||||
class Verifier:
|
||||
def __init__(self, F, g):
|
||||
self.F = F
|
||||
self.g = g
|
||||
@@ -76,7 +76,7 @@ class Verifier(object):
|
||||
c = hash_two_points(A, X)
|
||||
return self.g * int(z) == X * c + A
|
||||
|
||||
class Simulator(object):
|
||||
class Simulator:
|
||||
def __init__(self, F, g):
|
||||
self.F = F
|
||||
self.g = g
|
||||
@@ -92,7 +92,7 @@ class Simulator(object):
|
||||
# OR proof (with 2 parties)
|
||||
###
|
||||
|
||||
class ORProver_2parties(object):
|
||||
class ORProver_2parties:
|
||||
def __init__(self, F, g):
|
||||
self.F = F # Z_p
|
||||
self.g = g # elliptic curve generator
|
||||
@@ -126,7 +126,7 @@ class ORProver_2parties(object):
|
||||
# a real-world implementation would be shuffled
|
||||
return [c, self.c_1], [z, self.z_1]
|
||||
|
||||
class ORVerifier_2parties(object):
|
||||
class ORVerifier_2parties:
|
||||
def __init__(self, F, g):
|
||||
self.F = F
|
||||
self.g = g
|
||||
@@ -145,7 +145,7 @@ class ORVerifier_2parties(object):
|
||||
# OR proof (with n parties)
|
||||
###
|
||||
|
||||
class ORProver(object):
|
||||
class ORProver:
|
||||
def __init__(self, F, g):
|
||||
self.F = F # Z_p
|
||||
self.g = g # elliptic curve generator
|
||||
@@ -190,7 +190,7 @@ class ORProver(object):
|
||||
# a real-world implementation would be shuffled
|
||||
return self.cs, self.zs
|
||||
|
||||
class ORVerifier(object):
|
||||
class ORVerifier:
|
||||
def __init__(self, F, g):
|
||||
self.F = F
|
||||
self.g = g
|
||||
|
||||
Reference in New Issue
Block a user