mem notes

This commit is contained in:
Alex Ozdemir
2023-12-12 19:24:05 -08:00
parent a26533baad
commit 697c240148
16 changed files with 4413 additions and 0 deletions

1
doc/mem/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
build

12
doc/mem/Makefile Normal file
View File

@@ -0,0 +1,12 @@
.PHONY: main.pdf auto clean sync
main: build/main.pdf
build/main.pdf:
latexmk -pdf -halt-on-error -interaction=nonstopmode -shell-escape main.tex -outdir=build
auto:
latexmk -pvc -pdf -halt-on-error -interaction=nonstopmode -shell-escape main.tex -outdir=build
clean:
latexmk -C main.tex
rm -rf build

135
doc/mem/comments.sty Normal file
View File

@@ -0,0 +1,135 @@
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{comments}[2022/10/11 Inline and margin comments]
% Written by Alex Ozdemir
% Inspired by the peanutgallery package of Riad S. Wahby (and possibly others).
\RequirePackage{options}
\RequirePackage{xcolor}
\RequirePackage{etoolbox}
\newcounter{commentcoloruse}
\newcounter{commentcolorsave}
\newlength{\totalmargin}
\newcommand{\SaveColor}[1]{%
\expandafter\def\csname CommentColorNumber\thecommentcolorsave\endcsname{#1}%
\stepcounter{commentcolorsave}%
}
\newcommand{\GetColor}{%
\expandafter\csname CommentColorNumber\thecommentcoloruse\endcsname%
}
\newcommand{\NextColor}{%
\stepcounter{commentcoloruse}
}
\def\primerlist{}
\definecolor{BrewerQualitative0}{HTML}{1b9e77}
\definecolor{BrewerQualitative1}{HTML}{d95f02}
\definecolor{BrewerQualitative2}{HTML}{7570b3}
\definecolor{BrewerQualitative3}{HTML}{e7298a}
\definecolor{BrewerQualitative4}{HTML}{66a61e}
\definecolor{BrewerQualitative5}{HTML}{e6ab02}
\definecolor{BrewerQualitative6}{HTML}{a6761d}
\definecolor{BrewerQualitative7}{HTML}{666666}
\SaveColor{BrewerQualitative0}
\SaveColor{BrewerQualitative1}
\SaveColor{BrewerQualitative2}
\SaveColor{BrewerQualitative3}
\SaveColor{BrewerQualitative4}
\SaveColor{BrewerQualitative5}
\SaveColor{BrewerQualitative6}
\SaveColor{BrewerQualitative7}
\options{
/comments/.new family,
/comments/hide/.new toggle = false,
/comments/marginparsep/.new dim = \dimexpr1pt\relax,
/comments/marginparpush/.new dim = \dimexpr0.5em\relax,
/comments/marginparwidth/.new dim = \dimexpr0.5\totalmargin-2pt\relax,
}
\options@ProcessOptions{/comments}
\iftoggle{/comments/hide}{%
\newcommand{\InlineComment}[2]{}
\newcommand{\MarginComment}[2]{\unskip}
\newcommand{\changebars}[2]{[{\color{magenta}\em\begingroup{#1}\endgroup}][{\color{magenta}\sout{#2}}]}
}{%
\newcommand{\InlineComment}[2]{\begingroup \color{#1}{#2}\endgroup}
\newcommand{\MarginComment}[2]{\unskip{\color{#1}\vrule\vrule}{\marginpar{\raggedright\color{#1}\sffamily\selectfont\scriptsize #2}}}
\newcommand{\changebars}[2]{[{\color{magenta}\em\begingroup{#1}\endgroup}][{\color{magenta}\sout{#2}}]}
}
% \CommenterWithColor{INITIALS_ANYCASE}{COLORNAME}
\newcommand{\CommenterWithColor}[2]{
\uppercase{\def\commentcsuppercase{#1}}%
\lowercase{\def\commentcslowercase{#1}}%
\expandafter\newcommand\csname \commentcslowercase\endcsname[1]{%
\InlineComment{#2}{\uppercase{#1}: ##1}}
\expandafter\newcommand\csname \commentcsuppercase\endcsname[1]{%
\MarginComment{#2}{\uppercase{#1}: ##1}}
\expandafter\def\expandafter\primerlist\expandafter{\primerlist
\noindent\texttt{-} {\small\color{#2} \texttt{\textbackslash \lowercase{#1}\{Test\}}} creates an
inline comment:
\lowercase{\csname#1\endcsname}{Test}
\noindent\texttt{-} {\small\color{#2} \texttt{\textbackslash \uppercase{#1}\{Test\}}}
creates a margin comment:
\uppercase{\csname#1\endcsname}{Test}
}
}
\def\commentprimer{
\subsection*{Comment System}
\noindent Welcome to \texttt{comments.sty}.
\noindent Macros:
\noindent\texttt{-} {\small\texttt{\textbackslash Commenter\{AO\}}}
creates macros
{\small\texttt{\textbackslash ao}}
and
{\small\texttt{\textbackslash AO}}.
\noindent\texttt{-} {\small\texttt{\textbackslash
CommenterWithColor\{AO\}\{COLOR\_NAME\}}}
is similar.
\noindent\texttt{-} {\small\texttt{\textbackslash changebars\{new\}\{old\}}} yields
\changebars{new}{old}.
\noindent\texttt{-} {\small\texttt{\textbackslash commentprimer}}
outputs this help message.
\primerlist
\noindent Package options:
\noindent\texttt{-} \texttt{\small hide} hide all comments and apply changes
\noindent\texttt{-} \texttt{\small marginparpush=LEN} distance between comments
\noindent\texttt{-} \texttt{\small marginparsep=LEN} distance from column
\noindent\texttt{-} \texttt{\small marginparwidth=LEN} width
}
% Utility for expanding macro arguments to text before expanding the macro
\long\gdef\expandargumentsof#1#2\stopexpansion{%
\edef\tmp{\noexpand#1#2}\tmp%
}
\newcommand{\Commenter}[1]{
\expandargumentsof\CommenterWithColor{#1}{\GetColor}\stopexpansion
\NextColor
}
\AtEndPreamble{
\setlength{\totalmargin}{\dimexpr\paperwidth-\textwidth\relax}
\setlength{\marginparsep}{\option{/comments/marginparsep}}
\setlength{\marginparpush}{\option{/comments/marginparpush}}
\setlength{\marginparwidth}{\option{/comments/marginparwidth}}
}

48
doc/mem/der_xgcd/dnc.py Executable file
View File

@@ -0,0 +1,48 @@
#!/usr/bin/env python
from sage.misc.misc_c import prod
from sage.rings.finite_rings.finite_field_constructor import GF
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
p = 31
F = GF(p)
R = PolynomialRing(F, "x")
x = R.gen(0)
def v(*xs):
if len(xs) == 1 and isinstance(xs, list):
xs = xs[0]
return prod([x - a for a in xs])
def dgcd(p):
g, s, t = p.xgcd(p.derivative())
return g, s, t, s.factor(), t.factor()
f = v(2, 5, 7)
g = v(1, 3, 8)
print("f", f)
print("g", g)
_, fg, gf = f.xgcd(g)
print("fg", fg)
print("gf", gf)
_, fF, Ff = f.xgcd(f.derivative())
print("fF", fF)
print("Ff", Ff)
_, gG, Gg = g.xgcd(g.derivative())
print("gG", gG)
print("Gg", Gg)
h = f * g
print("h", h)
print("h", h.factor())
print("H", h.derivative().factor())
_, hH, Hh = h.xgcd(h.derivative())
print("hH", hH)
print("Hh", Hh)
c = Hh.coefficients()[-1]
print(dgcd(v(-1, -2, -3, -4, -5)))
print(dgcd(v(-1, -2, -3, -4)))
print(dgcd(v(-1, -2, -3)))
print(dgcd(v(-1, -2)))

53
doc/mem/macros.tex Normal file
View File

@@ -0,0 +1,53 @@
\newcommand{\xspacemm}{\ifmmode\else\xspace\fi}
\newcommand{\prover}{\ensuremath{\mathcal{P}}\xspacemm}
\newcommand{\verifier}{\ensuremath{\mathcal{V}}\xspacemm}
\newcommand{\constraints}{\ensuremath{\mathcal{C}}\xspacemm}
\newcommand{\FF}{\ensuremath{\mathbb{F}}\xspace}
\newcommand{\NN}{\ensuremath{\mathbb{N}}\xspace}
\newcommand{\zo}{\ensuremath{\{0,1\}}\xspace}
\newcommand{\ext}{\mathsf{Ext}\xspacemm}
\newcommand{\enc}{\mathsf{Enc}\xspacemm}
\newcommand{\Prove}{\mathsf{Prove}\xspacemm}
\newcommand{\Verify}{\mathsf{Verify}\xspacemm}
\newcommand{\negl}{\mathsf{negl}\xspacemm}
\newcommand{\rfrom}{\xleftarrow{\text{\$}}}
\newcommand{\MA}{\ensuremath{\mathcal{MA}}\xspacemm}
\newcommand{\NP}{\ensuremath{\mathcal{NP}}\xspacemm}
\newcommand{\ZoK}{ZoKrates\xspacemm}
\newcommand{\zkSNARK}{zkSNARK\xspacemm}
\newcommand{\zkSNARKs}{zkSNARKs\xspacemm}
\newcommand{\zsharp}{Z\#\xspacemm}
\newcommand{\pp}{\ensuremath{\mathsf{pp}}\xspacemm}
\newcommand{\bnds}{\ensuremath{\mathsf{bnds}}\xspacemm}
% Memory
\newcommand{\MemAcc}{\ensuremath{\mathsf{acc}}\xspacemm}
\newcommand{\MemWr}{\ensuremath{\mathsf{wr}}\xspacemm}
\newcommand{\MemAdr}{\ensuremath{\mathsf{adr}}\xspacemm}
\newcommand{\MemVal}{\ensuremath{\mathsf{val}}\xspacemm}
\newcommand{\MemTime}{\ensuremath{\mathsf{t}}\xspacemm}
\newcommand{\CtxElem}{\ensuremath{\mathsf{CtxElem}}\xspacemm}
\newcommand{\MsHash}{\ensuremath{{H_\text{r}}}\xspacemm}
\newcommand{\Uhf}{\ensuremath{{H_\text{c}}}\xspacemm}
% CIC/lean terms
\newcommand{\dbrk}[1]{\ensuremath{{[\![{#1}]\!]}}\xspacemm}
\newcommand{\nat}{\ensuremath{\texttt{nat}}\xspacemm}
\newcommand{\add}{\ensuremath{\texttt{add}}\xspacemm}
% Eval
\newcommand{\stdlib}{\ensuremath{\mathsf{stdlib}}\xspacemm}
\newcommand{\mathlib}{\ensuremath{\mathsf{mathlib}}\xspacemm}
\newcommand{\program}{\ensuremath{\mathsf{program}}\xspacemm}
% \let\oldvec\vec
\renewcommand{\vec}[1]{\ensuremath{\mathbf{#1}}\xspacemm}
\newcommand{\csPerA}[1]{{\color{blue}\ensuremath{#1\cdot A} constraints}}
\newcommand{\romCsPerA}[1]{{\color{purple}(ROM: \ensuremath{#1\cdot A} constraints)}}
\newcommand{\csPerN}[1]{{\color{red}\ensuremath{#1 \cdot N} constraints}}
\newcommand{\csPerT}[1]{{\color{blue}\ensuremath{#1\cdot 3A} constraints}}

134
doc/mem/main.tex Normal file
View File

@@ -0,0 +1,134 @@
\documentclass[conference,compsoc]{article}
%\documentclass[conference,compsoc]{IEEEtran}
%% \BibTeX command to typeset BibTeX logo in the docs
\AtBeginDocument{%
\providecommand\BibTeX{{%
\normalfont B\kern-0.5em{\scshape i\kern-0.25em b}\kern-0.8em\TeX}}}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[normalem]{ulem}
\usepackage[]{outlines}
\usepackage[dvipsnames]{xcolor}
\usepackage{amsmath,amssymb,comment}
\usepackage[bookmarksnumbered,unicode]{hyperref}
\hypersetup{ % ...like so
pdftex,
colorlinks,
pdfborder={0 0 0},
pdfmenubar=false,
pdfpagemode=UseNone,
pdfnonfullscreenpagemode=UseNone,
bookmarksopen=false,
bookmarks=false,
breaklinks=true,
linkcolor={green!50!black},
citecolor={red!50!black},
urlcolor={blue!50!black}
}
% add `hide` to hide comments
\usepackage[]{comments}
\Commenter{EL}
\Commenter{AO}
\Commenter{DB}
\usepackage[square,comma,numbers,sort&compress]{natbib}
\usepackage{xspace}
\usepackage[htt]{hyphenat}
\usepackage{listings}
\usepackage{nicefrac}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\tikzset{>=Latex[]}
\usepackage{booktabs}
\usepackage{menukeys}
\bibliographystyle{ieeetr}
\usepackage{caption}
\usepackage{subcaption}
% \usepackage[nohead,
% left=0.625in,right=0.625in,top=0.75in,bottom=0.75in,
% %left=0.633in,right=0.633in,top=0.75in,bottom=0.75in,
% columnsep=0.25in
% ]{geometry}
\usepackage{bussproofs}
\usepackage{backnaur}
% AO: Oakland minimum is 11pt, but that's crazy.
\usepackage{leading}
\newcommand\sysname{ZkPi\xspace}
\newcommand\sys{\sysname}
\newcommand\CIC{CIC\xspace}
\input{macros}
%\usepackage[text=DRAFT\ do\ not\ distribute,fontsize=0.08\paperwidth,angle=0,vpos=0.95\paperheight]{draftwatermark}
% careful
\hyphenation{an-aly-sis}
% Eddie Kohler protect us
\frenchspacing
\begin{document}
%%
%% The "title" command has an optional parameter,
\title{
%\vspace*{-1cm}
Persistent Memory
%\vspace*{-0.25cm}
}
%\subtitle{Shared Compiler Infrastructure for Constraint Solvers and Cryptosystems}
\author{}
% \author{%
% \IEEEauthorblockN{%
% Evan Laufer\quad
% Alex Ozdemir\quad
% Dan Boneh
% }%\\
% \IEEEauthorblockA{%
% Stanford University
% }
% }
%%
%% By default, the full list of authors will be used in the page %% headers. Often, this list is too long, and will overlap %% other information printed in the page headers. This command allows
%% the author to define a more concise list
%% of authors' names for this purpose.
%\renewcommand{\shortauthors}{Trovato and Tobin, et al.}
\maketitle
\begin{abstract}
TODO
% \input{abstract}
\end{abstract}
\commentprimer
\input{persistent}
\input{sparse}
\input{volatile}
\pagebreak
\begin{flushleft}
\footnotesize
\setlength{\parskip}{0pt}
\setlength{\itemsep}{0pt}
%\bibliographystyle{abbrv}
%\bibliography{myabbrev,cryptobib/crypto,refs}
\bibliography{refs}
\end{flushleft}
%% If your work has an appendix, this is the place to put it.
% \appendices
\end{document}
\endinput

5
doc/mem/models/Makefile Normal file
View File

@@ -0,0 +1,5 @@
data.csv: gcd_uniq.py
python $< > $@

1709
doc/mem/models/data.csv Normal file

File diff suppressed because it is too large Load Diff

38
doc/mem/models/gcd_uniq.py Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env python
from math import log2
def cost_gcd_uniq(N: int, r: int) -> (int, str):
return 6 * N, ""
def cost_bitsplit(N: int, r: int) -> (int, str):
return r * N, ""
def cost_sort(N: int, r: int) -> (int, str):
return 3 * (2**r + N), ""
def cost_subbitsplit(N: int, r: int) -> (int, str):
def cost_subbitsplit_window(N: int, r: int, k: int) -> int:
blocks = r // k
remainder = r - blocks * k
return 3 * 2**k + min(
3 * N * blocks + N * remainder, # bitsplit remainder
3 * N * (blocks + 2), # double-window remainder
)
cost, _, k = min([(cost_subbitsplit_window(N, r, k), -k, k) for k in range(1, r + 1)])
return cost, f"{k}"
print("log2_accesses,addr_bits,name,cost,k")
for r in range(4, 65):
for N in [2**i for i in range(0, 21, 3)]:
for f in [cost_bitsplit, cost_sort, cost_subbitsplit, cost_gcd_uniq]:
name = f.__name__.removeprefix("cost_")
cost, note = f(N, r)
log2N = int(log2(N))
print(f"{log2N},{r},{name},{float(cost)},{note}")

22
doc/mem/models/plot.R Normal file
View File

@@ -0,0 +1,22 @@
library(tidyverse)
d <- read_csv("data.csv")
with_norm_cost <- d %>%
left_join(d %>%
filter(name == "gcd_uniq") %>%
mutate(norm_cost = cost) %>%
select(log2_accesses, addr_bits, norm_cost) %>%
mutate(),
by=c("log2_accesses", "addr_bits")) %>%
mutate(norm_cost = cost / norm_cost)
with_norm_cost %>%
filter(name != "sort") %>%
ggplot(aes(x = addr_bits, y = norm_cost, color = name)) +
geom_point() +
geom_line() +
facet_wrap(vars(log2_accesses), scales = "free", labeller = label_both)
d %>%
filter(name == "subbitsplit") %>%
ggplot(aes(x = addr_bits, y = k)) +
geom_point() +
geom_line() +
facet_wrap(vars(log2_accesses), scales = "free", labeller = label_both)

120
doc/mem/persistent.tex Normal file
View File

@@ -0,0 +1,120 @@
\section{Persistent}
\begin{outline}
\1 initial definitions
\2 \FF: target field
\2 $N$: persistent array size
\2 $\vec a, \vec b \in \FF^N$: initial and final arrays
\2 $c_a, c_b$: commitments to arrays with randomness $r_a, r_b$
\2 $R$: a witness relation $R(c_a, c_b, x, \vec a, \vec b, w, r_a, r_b)$ for a CP-SNARK
\3 $x$ extra instance material
\3 $w$ extra witness material
\3 $\vec a$ represents the initial state of a RAM that $R$ makes $A$
accesses to; $\vec b$ is the final state.
\2 $A$: number of accesses
\2 $[A]$: $\{0, \dots, A-1\}$
\2 hashes
\3 root hash: $H_r(k, \vec x) = \prod_i (x_i - k)$
\4 used for ``permutation arguments''
\4 used to hash multisets to scalars
\3 coefficient hash: $H_c(k, \vec x) = \sum_{i=0} k^ix_i$
\4 used to hash vectors to scalars
\1 coalesce the memory footprint
\2 goal: from the $N$ entries, isolate up to $A$ that $R$ will be able to
touch
\3 route the remaining entries from $\vec a$ to $\vec b$ as cheaply as
possible
\2 witness: $\vec c$: $A$ index-value pairs of $\vec a$ including all touched entries.
\2 witness: $\vec d$: similar, with $\vec b$ (same indices and order).
\2 challenge $\alpha$
\2 compute $\vec a'$, defined by $a'_i = H_c(\alpha, (a_i, i))$ and $\vec b'$ similarly
\3 free (linear)
\2 compute $\vec c'$, a length $N$ vector
\3 First $A$ entries: root-hashes, similarly from $\vec c$.
\4 $v + \alpha i$
\4 \csPerA{1} (could share with main?)
\3 For the rest, hashes of other $\vec a$ entries, in original order (witness)
\2 compute $\vec d'$ similarly, from $\vec d$ and $\vec b$.
\3 \csPerA{1}
\2 challenge $\beta$
\2 equate last $N-A$ entries of $\vec c'$ and $\vec d'$.
\3 free (linear)
\2 permutation arguments for $\vec a', \vec c'$ and $\vec b', \vec d'$ (key $\beta$)
\3 \csPerN{3} + \csPerA{2}
\3 because some is shared.
\2 outputs
\3 $\vec c$ initial index-value pairs
\3 $\vec d$ final index-value pairs
\1 build the main transcript
\2 goal: define access-order and index-order transcripts, and ensure they're
permutations of one another
\2 $T$: number of entries ($3A$)
\2 entries: (value, idx, time, write?, create?, active?)
\3 create is a bit that is set if this is an access writing from the initial persistent RAM
\3 active is a bit that is set if this \textbf{write} is active (it's always set for reads)
\4 if inactive, this write has no effect.
\3 times are in $[A+1]$, not $[3A]$
\4 accesses from $R$ gets times in $[A]$, as standard
\4 all initial writes to have time 0
\4 all final reads have time $A$
\2 denote the transcript $\vec e$
\2 witness: $\vec f$: the transcript ordered on index and then time
\2 challenge $\alpha$
\2 compute $\vec e'$ with element-wise coefficient hash over $\vec e$ keyed on $\alpha$.
\3 The computations is something like $v + \alpha i + k_2 \alpha^2 + w \alpha^3 + k_4 \alpha^4 + k_5 \alpha^5$
\4 $w$ is write
\3 The $k$'s are all fixed
\3 \csPerT{2} - \csPerA{2}
\4 the minus is b/c the $w$s are fixed
for the initialization and finalization accesses
\3 Furthermore, the single non-linear product $\alpha i$ is shared with the
hashes needed for coalescing.
\2 compute $\vec f'$ similarly from $\vec f$
\3 \csPerT{5} for hashing
\3 the hash ensures well-formedness for booleans
\2 challenge $\beta$
\2 permutation argument for $\vec e', \vec f'$ (key $\beta$)
\3 \csPerT{2}
\2 three properties remain to be checked
\3 transcript is grouped by index
\3 within that, sorted by time
\3 read-over-write semantics
\4 with no writing to fresh indices
\1 checking the index-order transcript
\2 goal: check array semantics (modulo residual range checks)
\2 Refer to one entry as $(v, i, t, w, c, a)$ and the next as $(v', i', t', w', c', a')$
\2 First, redef $w'$ to be $w'$ if $a=1$, else $w$
\3 \csPerT{1}
\2 Recall that the ranges of each value are ensured by hashing
\3 $i \in [N]$
\3 $t \in [A+1]$
\3 $w, c, a \in \zo$
\2 rules:
\3 start with a create
\3 $t$ grows or next $c=1$
\3 $v$ is constant or next $w=1$
\3 $i$ is constant or next $c=1$
\2 constraints:
\3 $c_0 = 1$
\3 $(v'-v)(w'-1)=0$
\3 $(i'-i)(c'-1)=0$
\3 compute $\Delta_t = (1-c')(t'-t)$
\3 cost: \csPerT{3}
\4 and range check
\4 and one for $c_0 = 1$
\3 we must show (next section) that each $\Delta_t \in [A+1]$
\1 range check
\2 goal: check that each $\Delta_t$ is in $[A+1]$
\2 let $\vec g$ denote all $\Delta_t$s concatenated to $[A+1]$ (length $4A+1$)
\2 witness $\vec h$: sort $\vec g$
\3 check that each delta is 0 or 1. \csPerA{4}
\2 challenge $\alpha$
\2 permutation argument for $\vec g, \vec h$ (key $\alpha$)
\3 \csPerA{8}
\1 Accounting
\2 two verifier challenges ($\alpha,\beta$)
\2 \csPerN{3}
\3 plus an extra MSM of size $2\cdot N$.
\2 \csPerA{53}
\3 The cost of a linear scan (per element scanned) is $3$ by my reckoning
\3 So if $A < 53/3 < 18$, you should do linear scans instead.
\end{outline}

1985
doc/mem/refs.bib Normal file

File diff suppressed because it is too large Load Diff

1
doc/mem/sage/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.sage.py

31
doc/mem/sage/poly.sage Normal file
View File

@@ -0,0 +1,31 @@
P = PolynomialRing(GF(17), "X")
X = P.gen(0)
p = (X-1)*(X-3)*(X-7)*(X-10)
p_prime = p.derivative()
def poly_gcd_ext_int(x, y, x_c_a, x_c_b, y_c_a, y_c_b):
if x == 0:
lc = y.leading_coefficient()
return y/lc, y_c_a/lc, y_c_b/lc
# x = a * x_c_a + b * x_c_b
# y = a * y_c_a + b * y_c_b
if x.degree() > y.degree():
return poly_gcd_ext_int(y, x, y_c_a, y_c_b, x_c_a, x_c_b)
# y = qx + r r = y - qx
q, r = y.quo_rem(x)
r_c_a = y_c_a - q*x_c_a
r_c_b = y_c_b - q*x_c_b
return poly_gcd_ext_int(r, x, r_c_a, r_c_b, x_c_a, x_c_b)
# (a, b) = (r, a)
def poly_gcd_ext(x, y):
g, a, b = poly_gcd_ext_int(x, y, 1, 0, 0, 1)
assert g == x.gcd(y)
assert a * x + b * y == g
return g, a, b
g, a, b = poly_gcd_ext(p, p_prime)
print(g)
print(a)
print(b)
print(a*p+b*p_prime)

33
doc/mem/sparse.tex Normal file
View File

@@ -0,0 +1,33 @@
\section{Sparse Persistent}
We want to use (nearly) the whole field
as our index space, without cost.
\begin{outline}
\1 What if you want $\vec a$ and $\vec b$ to be index-value pairs, where the
indices are from a large space (rather than $[N]$)?
\1 params
\2 Now, $N$ becomes the capacity
\2 $C$ is the number of creations
\1 Three operations:
\2 read
\2 conditional write
\2 create
\3 these happen *before* the reads/writes
\1 approach
\2 use a dummy key value to indicate dead spots
\3 zero is a natural choice
\2 essentially, you inject creates into the initial store,
and filter out some dummies afterwards
\2 you just add a conditional uniqueness check
\3 uniqueness check: \csPerN{4}
\3 with a condition: \csPerN{2}
\3 computing the condition (field eq): \csPerN{2}
\2 base cost of the permutation: \csPerN{4}
\3 one from initial coefficient hash
\3 one from root hash
\3 one from root hash again
\3 one from coefficient hash again
\1 accounting
\2 \csPerN{12}
\2 very similar dependence on $A$
\2 some dependence on $C$ too (like 10--30)
\end{outline}

86
doc/mem/volatile.tex Normal file
View File

@@ -0,0 +1,86 @@
\section{Volatile}
\begin{outline}
\1 initial definitions
\2 \FF: target field
\2 $N$: RAM size
\2 reads from uninit memory are undefined
\2 $R$: a witness relation $R(x, w)$ for a CC-SNARK
\3 $A$: number of RAM accesses
\4 each access is a conditional write
\1 build the main transcript
\2 goal: define access-order and index-order transcripts, and ensure they're
permutations of one another
\2 entries: (value, idx, time, write?, active?) $(v, i, t, w, a)$
\3 write indicates read/write.
\3 active is a bit that is set for a write if it takes effect; otherwise, it has no effect. It is always set for reads.
\3 times are in $[A]$
\3 ROM case: entries are (value, idx)
\2 $\vec a$: time-order access sequence
\2 witness: $\vec b$: index-order access sequence
\2 challenge $\alpha$
\2 compute $\vec a'$: coefficient-hashes of time-order accesses with key
$\alpha$.
\3 Since time and write are fixed, \csPerA{2}.
\2 compute $\vec b'$: same for $\vec b$
\3 \csPerA{4}
\2 challenge $\beta$, use root-hash to do permutation argument
\3 \csPerA{2}
\1 check the index-order transcript
\2 adjacent entries: $(v, i, t, w, a)$ and then $(v', i', t', w', a')$
\2 rules:
\3 (A) values can change only if indices do, or if $w'=1$
\3 (B) times increase, or indices change
\3 (C) first indices in index-constant blocks are unique
\2 witness sequence $\vec d$ that indicates index change
\3 defined by $d_0=1$ and $d'=1$ if $i \ne i'$, else $d'=0$
\3 cost: \csPerA{2}
\2 compute $\delta_t = (t'-t)(1-d')$. \csPerA{1}
\2 compute $v_p = d'(s-v) + v$. \csPerA{1}
\2 redef $v'$ to $v'$ if $a$, else $v$. \csPerA{1}
\2 $(v'-v_p)(1-w')=0$ \csPerA{1}
\2 range-check $\delta_t$s (next section)
\1 uniqueness check
\2 define polynomial $p(X)$ by $\prod_j (w_j(X - i_j - 1) + 1)$
\2 it's derivative is $p'(X)$
\2 for an index-order transcript, $\gcd(p,p')=1$
\3 so there exist polynomials $f,g$ of degree at most $A-1$ such that $1 = pf + p'g$
\2 witness $\vec f$ of length $A$ is the coefficients of $f$
\2 witness $\vec g$ of length $A$ is the coefficients of $g$
\2 challenge $\gamma$ (same round as $\beta$)
\2 check $p(\gamma)f(\gamma) + p'(\gamma)g(\gamma)=1$
\2 eval $f(\gamma), g(\gamma)$: \csPerA{2} total
\2 eval $p(\gamma)$: \csPerA{2}
\3 one constraint for conditional
\3 one for product accumulation
\2 eval $p'(\gamma)$: \csPerA{2}
\3 as $p(\gamma)\sum_j\frac{p(\gamma)}{\gamma-i_j}$
\3 one constraint for inversion
\3 one constraint for conditional
\3 sum is free
\1 range check
\2 concat $\delta_t$s and $[A]$
\2 sort (length $2A$)
\2 check const-or-plus-1 \csPerA{2}
\2 permutation check $(\beta)$ \csPerA{4}
\1 accounting
\2 \csPerA{26}
\1 ROM case
\2 assume $A$ reads, including at least one read to every index
\2 entries are (value, idx)
\2 permutation argument: \romCsPerA{4}
\2 checking the sorted transcript:
\3 adjacent entries $(i, v), (i', v')$
\3 logically:
\4 $i = i' \lor i + 1 = i'$
\4 $i = i' \implies v = v'$ ($i \ne i' \lor v = v'$)
\3 R1CS:
\4 $(i'-i)(i'-i-1)=0$
\4 $(i'-i)r(v'-v)=(v'-v)$
\4 \romCsPerA{3}
\3 some boundary conditions
\2 accounting: {\color{purple}{$7\cdot A$}}
\3 values of size $\ell$: {\color{purple}{$(5 + 2\ell)\cdot A$}}
\4 NB: to get this, process value equalities over value \textit{hashes}
\end{outline}