Update to latest version
@@ -6,5 +6,6 @@ https://arnaucube.com/blog
|
||||
- Install [blogo](https://github.com/arnaucube/blogo)
|
||||
- Edit the files from `/blogo-input`
|
||||
- Execute `blogo` to generate the html files
|
||||
- Alternatively, execute `blogo -d` to serve the files at `http://127.0.0.1:8080/blog/`
|
||||
|
||||
More details: https://github.com/arnaucube/blogo
|
||||
|
||||
@@ -8,10 +8,20 @@
|
||||
"metadescr": "arnaucube blog",
|
||||
"metaimg": "img/logoArnauCube.png",
|
||||
"posts": [
|
||||
{
|
||||
"thumb": "powersoftau_thumb.md",
|
||||
"md": "powersoftau.md",
|
||||
"metadescr": "In the following notes we go over the ideas behind the Powers of Tau ceremony, how participants contribute and how the contributions are verified (logic & code). We focus on the Ethereum's upcoming KZG-Ceremony."
|
||||
},
|
||||
{
|
||||
"thumb": "ringsig_thumb.md",
|
||||
"md": "ringsig.md",
|
||||
"metadescr": "Notes on ring signatures"
|
||||
},
|
||||
{
|
||||
"thumb": "shamir-secret-sharing_thumb.md",
|
||||
"md": "shamir-secret-sharing.md",
|
||||
"metadescr": ""
|
||||
"metadescr": "Overview of Langrange Polynomial interpolation and Shamir's secret sharing."
|
||||
},
|
||||
{
|
||||
"thumb": "kzg-batch-proof_thumb.md",
|
||||
@@ -51,6 +61,7 @@
|
||||
"css",
|
||||
"img",
|
||||
"vendor",
|
||||
"js"
|
||||
"js",
|
||||
"notes.html"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,10 +12,16 @@ body {
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
.dark-theme img, .dark-theme video, .dark-theme iframe, .dark-theme .onoffswitch-label, .dark-theme code {
|
||||
/* .dark-theme img, .dark-theme video, .dark-theme iframe, .dark-theme .onoffswitch-label, .dark-theme code { */
|
||||
.dark-theme img, .dark-theme video, .dark-theme iframe, .dark-theme .onoffswitch-label {
|
||||
filter: invert(100%) hue-rotate(180deg);
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #fafafa;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration:none!important;
|
||||
}
|
||||
|
||||
BIN
blogo-input/img/posts/powersoftau/kzg-ceremony-screenshot.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
blogo-input/img/posts/ring-sig/box-closed.png
Normal file
|
After Width: | Height: | Size: 255 KiB |
BIN
blogo-input/img/posts/ring-sig/step00.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
blogo-input/img/posts/ring-sig/step01.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
blogo-input/img/posts/ring-sig/step02.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
blogo-input/img/posts/ring-sig/step03.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
blogo-input/img/posts/ring-sig/step04.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
blogo-input/img/posts/ring-sig/step05.png
Normal file
|
After Width: | Height: | Size: 138 KiB |
BIN
blogo-input/img/posts/ring-sig/step06.png
Normal file
|
After Width: | Height: | Size: 163 KiB |
@@ -19,6 +19,8 @@
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -26,7 +28,8 @@
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css">
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
@@ -39,7 +42,11 @@
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<a href="/blog" style="color:#000;">Blog index</a>
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
@@ -60,6 +67,9 @@
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
@@ -129,7 +139,7 @@
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
|
||||
133
blogo-input/js/drawdown.js
Normal file
@@ -0,0 +1,133 @@
|
||||
// Code from the repo: https://github.com/adamvleggett/drawdown
|
||||
//
|
||||
|
||||
/**
|
||||
* drawdown.js
|
||||
* (c) Adam Leggett
|
||||
*/
|
||||
|
||||
|
||||
;function markdown(src) {
|
||||
|
||||
var rx_lt = /</g;
|
||||
var rx_gt = />/g;
|
||||
var rx_space = /\t|\r|\uf8ff/g;
|
||||
var rx_escape = /\\([\\\|`*_{}\[\]()#+\-~])/g;
|
||||
var rx_hr = /^([*\-=_] *){3,}$/gm;
|
||||
var rx_blockquote = /\n *> *([^]*?)(?=(\n|$){2})/g;
|
||||
var rx_list = /\n( *)(?:[*\-+]|((\d+)|([a-z])|[A-Z])[.)]) +([^]*?)(?=(\n|$){2})/g;
|
||||
var rx_listjoin = /<\/(ol|ul)>\n\n<\1>/g;
|
||||
var rx_highlight = /(^|[^A-Za-z\d\\])(([*_])|(~)|(\^)|(--)|(\+\+)|`)(\2?)([^<]*?)\2\8(?!\2)(?=\W|_|$)/g;
|
||||
var rx_code = /\n((```|~~~).*\n?([^]*?)\n?\2|(( .*?\n)+))/g;
|
||||
var rx_link = /((!?)\[(.*?)\]\((.*?)( ".*")?\)|\\([\\`*_{}\[\]()#+\-.!~]))/g;
|
||||
var rx_table = /\n(( *\|.*?\| *\n)+)/g;
|
||||
var rx_thead = /^.*\n( *\|( *\:?-+\:?-+\:? *\|)* *\n|)/;
|
||||
var rx_row = /.*\n/g;
|
||||
var rx_cell = /\||(.*?[^\\])\|/g;
|
||||
var rx_heading = /(?=^|>|\n)([>\s]*?)(#{1,6}) (.*?)( #*)? *(?=\n|$)/g;
|
||||
var rx_para = /(?=^|>|\n)\s*\n+([^<]+?)\n+\s*(?=\n|<|$)/g;
|
||||
var rx_stash = /-\d+\uf8ff/g;
|
||||
|
||||
function replace(rex, fn) {
|
||||
src = src.replace(rex, fn);
|
||||
}
|
||||
|
||||
function element(tag, content) {
|
||||
return '<' + tag + '>' + content + '</' + tag + '>';
|
||||
}
|
||||
|
||||
function blockquote(src) {
|
||||
return src.replace(rx_blockquote, function(all, content) {
|
||||
return element('blockquote', blockquote(highlight(content.replace(/^ *> */gm, ''))));
|
||||
});
|
||||
}
|
||||
|
||||
function list(src) {
|
||||
return src.replace(rx_list, function(all, ind, ol, num, low, content) {
|
||||
var entry = element('li', highlight(content.split(
|
||||
RegExp('\n ?' + ind + '(?:(?:\\d+|[a-zA-Z])[.)]|[*\\-+]) +', 'g')).map(list).join('</li><li>')));
|
||||
|
||||
return '\n' + (ol
|
||||
? '<ol start="' + (num
|
||||
? ol + '">'
|
||||
: parseInt(ol,36) - 9 + '" style="list-style-type:' + (low ? 'low' : 'upp') + 'er-alpha">') + entry + '</ol>'
|
||||
: element('ul', entry));
|
||||
});
|
||||
}
|
||||
|
||||
function highlight(src) {
|
||||
return src.replace(rx_highlight, function(all, _, p1, emp, sub, sup, small, big, p2, content) {
|
||||
return _ + element(
|
||||
emp ? (p2 ? 'strong' : 'em')
|
||||
: sub ? (p2 ? 's' : 'sub')
|
||||
: sup ? 'sup'
|
||||
: small ? 'small'
|
||||
: big ? 'big'
|
||||
: 'code',
|
||||
highlight(content));
|
||||
});
|
||||
}
|
||||
|
||||
function unesc(str) {
|
||||
return str.replace(rx_escape, '$1');
|
||||
}
|
||||
|
||||
var stash = [];
|
||||
var si = 0;
|
||||
|
||||
src = '\n' + src + '\n';
|
||||
|
||||
replace(rx_lt, '<');
|
||||
replace(rx_gt, '>');
|
||||
replace(rx_space, ' ');
|
||||
|
||||
// blockquote
|
||||
src = blockquote(src);
|
||||
|
||||
// horizontal rule
|
||||
replace(rx_hr, '<hr/>');
|
||||
|
||||
// list
|
||||
src = list(src);
|
||||
replace(rx_listjoin, '');
|
||||
|
||||
// code
|
||||
replace(rx_code, function(all, p1, p2, p3, p4) {
|
||||
stash[--si] = element('pre', element('code', p3||p4.replace(/^ /gm, '')));
|
||||
return si + '\uf8ff';
|
||||
});
|
||||
|
||||
// link or image
|
||||
replace(rx_link, function(all, p1, p2, p3, p4, p5, p6) {
|
||||
stash[--si] = p4
|
||||
? p2
|
||||
? '<img src="' + p4 + '" alt="' + p3 + '"/>'
|
||||
: '<a href="' + p4 + '">' + unesc(highlight(p3)) + '</a>'
|
||||
: p6;
|
||||
return si + '\uf8ff';
|
||||
});
|
||||
|
||||
// table
|
||||
replace(rx_table, function(all, table) {
|
||||
var sep = table.match(rx_thead)[1];
|
||||
return '\n' + element('table',
|
||||
table.replace(rx_row, function(row, ri) {
|
||||
return row == sep ? '' : element('tr', row.replace(rx_cell, function(all, cell, ci) {
|
||||
return ci ? element(sep && !ri ? 'th' : 'td', unesc(highlight(cell || ''))) : ''
|
||||
}))
|
||||
})
|
||||
)
|
||||
});
|
||||
|
||||
// heading
|
||||
replace(rx_heading, function(all, _, p1, p2) { return _ + element('h' + p1.length, unesc(highlight(p2))) });
|
||||
|
||||
// paragraph
|
||||
replace(rx_para, function(all, content) { return element('p', unesc(highlight(content))) });
|
||||
|
||||
// stash
|
||||
replace(rx_stash, function(all) { return stash[parseInt(all)] });
|
||||
|
||||
return src.trim();
|
||||
};
|
||||
|
||||
94
blogo-input/js/highlightjs/atom-one-light.css
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
|
||||
Atom One Light by Daniel Gamage
|
||||
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
|
||||
|
||||
base: #fafafa
|
||||
mono-1: #383a42
|
||||
mono-2: #686b77
|
||||
mono-3: #a0a1a7
|
||||
hue-1: #0184bb
|
||||
hue-2: #4078f2
|
||||
hue-3: #a626a4
|
||||
hue-4: #50a14f
|
||||
hue-5: #e45649
|
||||
hue-5-2: #c91243
|
||||
hue-6: #986801
|
||||
hue-6-2: #c18401
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
color: #383a42;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #a0a1a7;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #a626a4;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e45649;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #0184bb;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta .hljs-string {
|
||||
color: #50a14f;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #986801;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #4078f2;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-title.class_,
|
||||
.hljs-class .hljs-title {
|
||||
color: #c18401;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
134
blogo-input/notes.html
Normal file
@@ -0,0 +1,134 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta name="description" content="[blogo-summary]" />
|
||||
<meta charset="utf-8">
|
||||
<title>Notes</title>
|
||||
<meta name="title" content="Notes">
|
||||
<meta name="description" content="Notes">
|
||||
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- o_gradient_background" -->
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
<input onclick="switchTheme()" type="checkbox" name="onoffswitch" class="onoffswitch-checkbox"
|
||||
id="themeSwitcher">
|
||||
<label class="onoffswitch-label" for="themeSwitcher"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img style="height:5px; width:100%; margin-top:8px;" src="img/gradient-line.jpg" />
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
<!-- in markdown which later is converted to html -->
|
||||
<div id="markdown" class="container" style="margin-top:40px;max-width:800px;">
|
||||
### Notes:
|
||||
Usually while reading papers I take handwritten notes, this section contains some of them re-written to LaTeX.
|
||||
The notes are not complete, don’t include all the steps neither the explanations neither most of the proofs.
|
||||
I use these notes to revisit the concepts after some time of reading the paper.
|
||||
- [Notes on Halo](https://raw.githubusercontent.com/arnaucube/math/master/notes_halo.pdf)
|
||||
- [Notes on Sigma protocol and OR proofs](https://raw.githubusercontent.com/arnaucube/math/master/sigma-or-notes.pdf)
|
||||
- [Notes on BLS signatures](https://raw.githubusercontent.com/arnaucube/math/master/notes_bls-sig.pdf)
|
||||
- [Notes on Sonic](https://raw.githubusercontent.com/arnaucube/math/master/notes_sonic.pdf)
|
||||
- [Notes on Weil Pairing](https://raw.githubusercontent.com/arnaucube/math/master/pairings.pdf)
|
||||
</div>
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Back to the blog</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
style="color:gray;text-decoration:none;"
|
||||
target="_blank">twitter.com/arnaucube</a>
|
||||
</li>
|
||||
<li><a href="https://github.com/arnaucube"
|
||||
style="color:gray;text-decoration:none;"
|
||||
target="_blank">github.com/arnaucube</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
renderMathInElement(document.body, {
|
||||
displayMode: false,
|
||||
// customised options
|
||||
// • auto-render specific keys, e.g.:
|
||||
delimiters: [
|
||||
{left: '$$', right: '$$', display: true},
|
||||
{left: '$', right: '$', display: false},
|
||||
{left: "\\[", right: "\\]", display: true},
|
||||
{left: "\\(", right: "\\)", display: false},
|
||||
],
|
||||
// • rendering keys, e.g.:
|
||||
throwOnError : true
|
||||
});
|
||||
});
|
||||
|
||||
///
|
||||
let theme = localStorage.getItem("theme");
|
||||
if ((theme === "light-theme")||(theme==null)) {
|
||||
theme = "light-theme";
|
||||
document.getElementById("themeSwitcher").checked = false;
|
||||
} else if (theme === "dark-theme") {
|
||||
theme = "dark-theme";
|
||||
document.getElementById("themeSwitcher").checked = true;
|
||||
}
|
||||
document.body.className = theme;
|
||||
localStorage.setItem("theme", theme);
|
||||
|
||||
function switchTheme() {
|
||||
theme = localStorage.getItem("theme");
|
||||
if (theme === "light-theme") {
|
||||
theme = "dark-theme";
|
||||
document.getElementById("themeSwitcher").checked = true;
|
||||
} else {
|
||||
theme = "light-theme";
|
||||
document.getElementById("themeSwitcher").checked = false;
|
||||
}
|
||||
document.body.className = theme;
|
||||
localStorage.setItem("theme", theme);
|
||||
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="js/drawdown.js"></script>
|
||||
|
||||
<script>
|
||||
let content = document.getElementById("markdown").innerHTML;
|
||||
let md = markdown(content);
|
||||
document.getElementById("markdown").innerHTML = md;
|
||||
</script>
|
||||
|
||||
<script src="js/external-links.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
> **Warning**: I want to state clearly that I'm not a mathematician, I'm just an amateur on math studying in my free time, and this article is just an attempt to try to sort the notes that I took while reading about the KZG Commitments.
|
||||
|
||||
Last week I posted some *[notes on KZG Commitmens](https://arnaucube.com/blog/kzg-commitments.html)*, which overviews the scheme for single proofs. The current notes, try to overview the *batch proof* iteraton on KZG Commitments, and the *vector commitment* usage of it. Again (as in the previous post), big thanks to [Dankrad Feist](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html) and [Alin Tomescu](https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html) for their articles which helped me to follow a bit the reasoing behind this, and again, I recommend spending the time reading their articles instead of this current notes.
|
||||
Last week I posted some *[notes on KZG Commitmens](https://arnaucube.com/blog/kzg-commitments.html)*, which overviews the scheme for single proofs. The current notes, try to overview the *batch proof* iteraton on KZG Commitments, and the *vector commitment* usage of it. Again (as in the previous post), big thanks to [Dankrad Feist](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html) and [Alin Tomescu](https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html) for their articles which helped me to follow a bit the reasoing behind this, and again, I recommend spending the time **reading their articles ([1](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html), [2](https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html)) instead of this current notes**.
|
||||
|
||||
|
||||
#### Batch proof
|
||||
@@ -12,11 +12,11 @@ Let $(z_0, y_0), (z_1, y_1), ..., (z_k, y_k)$ be the points that we want to proo
|
||||
The *commitment* to the polynomial stands the same than for single proofs: $c=[p(\tau)]_1$.
|
||||
|
||||
For the evaluation proof, while in the single proofs we compute $q(x) = \frac{p(x)-y}{x-z}$, we will replace $y$ and $x-z$ by the following two polynomials.
|
||||
The constant $y$ is replaced by a polynomial that has roots at all the points that we want to prove. This is achieved by computing the [Lagrange interpolation](/blog/shamir-secret-sharing.html#lagrange-polynomial%20interpolation) for the given set of points:
|
||||
The constant $y$ is replaced by a polynomial that has roots at all the points that we want to prove. This is achieved by computing the [Lagrange interpolation](shamir-secret-sharing.html#lagrange-polynomial%20interpolation) for the given set of points:
|
||||
|
||||
$$
|
||||
I(x) = \sum_{j=0}^k y_j l_j(x)\newline
|
||||
where \space\space\space l_j(x) = \prod\_{0\leq m \leq k} \frac{x-x_m}{x_j - x_m}
|
||||
where \space\space\space l_j(x) = \prod_{0\leq m \leq k} \frac{x-x_m}{x_j - x_m}
|
||||
$$
|
||||
|
||||
And the $x-z$, which was to ensure that $q(x)$ had a root at $z$, now, as we want to ensure that $q(x)$ has roots at all the points of the commitment, we will use the *zero polynomial*:
|
||||
@@ -57,4 +57,4 @@ We can use KZG Commitments as a vector commitment scheme by mapping the *vector*
|
||||
#### Final note
|
||||
I'm fascinated by this scheme and its potential. One next rabbit hole (related to KZG Commitments) to look at, would be the [Plonk](https://vitalik.ca/general/2019/09/22/plonk.html) and other similar constructions. Also, another use case that is getting attention in the Ethereum community is the [*Verkle Trees*](https://vitalik.ca/general/2021/06/18/verkle.html).
|
||||
|
||||
As in the previous notes, in order to try to put in practice the concepts, I've added the *batch proof* logic at https://github.com/arnaucube/kzg-commitments-study.
|
||||
As in the previous notes, in order to try to put in practice the concepts, I've added the implementation of the *batch proof* logic at the Go KZG implementation https://github.com/arnaucube/kzg-commitments-study.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
> **Warning**: I want to state clearly that I'm not a mathematician, I'm just an amateur on math studying in my free time, and this article is just an attempt to try to sort the notes that I took while reading about the KZG Commitments.
|
||||
|
||||
Few weeks ago I started reading about [KZG Commitments](https://www.iacr.org/archive/asiacrypt2010/6477178/6477178.pdf) from the articles written by [Dankrad Feist](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html), by [Tom Walton-Pocock](https://hackmd.io/@tompocock/Hk2A7BD6U) and by [Alin Tomescu](https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html). I want to thank them, because their articles helped me to understand a bit the concepts. I recommend spending the time reading their articles instead of this current notes.
|
||||
Few weeks ago I started reading about [KZG Commitments](https://www.iacr.org/archive/asiacrypt2010/6477178/6477178.pdf) from the articles written by [Dankrad Feist](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html), by [Tom Walton-Pocock](https://hackmd.io/@tompocock/Hk2A7BD6U) and by [Alin Tomescu](https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html). I want to thank them, because their articles helped me to understand a bit the concepts. I recommend spending the time reading their articles ([1](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html), [2](https://hackmd.io/@tompocock/Hk2A7BD6U), [3](https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html)) instead of this current notes.
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
@@ -79,7 +79,7 @@ $$
|
||||
We can see that is the equation $q(x)(x-z)=p(x)-y$, which can be expressed as $q(x) = \frac{p(x) - y}{x-z}$, evaluated at $\tau$ from the *trusted setup*, which is not known: $q(\tau) = \frac{p(\tau) - y}{\tau-z}$.
|
||||
|
||||
### Conclusions
|
||||
The content covered in this notes is just a quick overview, but allows us to see the potential of the scheme. One next iteration from what we've seen is the approach to do batch proofs, which allows us to evaluate at multiple points with a single evaluation proof. This scheme can be used as a *vector commitment*, using a polynomial where the $p(i) = x_i$ for all values of $x_i$ of the vector, which can be obtained from the $x_i$ values and computing the [Lagrange interpolation](https://en.wikipedia.org/wiki/Lagrange_polynomial). This is quite useful combined with the mentioned batch proofs. The *batch proofs* logic can be found at the [blog/kzg-batch-proof](https://arnaucube.com/blog/kzg-batch-proof.html) notes (kind of the continuation of the current notes).
|
||||
The content covered in this notes is just a quick overview, but allows us to see the potential of the scheme. One next iteration from what we've seen is the approach to do batch proofs, which allows us to evaluate at multiple points with a single evaluation proof. This scheme can be used as a *vector commitment*, using a polynomial where the $p(i) = x_i$ for all values of $x_i$ of the vector, which can be obtained from the $x_i$ values and computing the [Lagrange interpolation](shamir-secret-sharing.html#lagrange-polynomial%20interpolation). This is quite useful combined with the mentioned batch proofs. The *batch proofs* logic can be found at the [blog/kzg-batch-proof](https://arnaucube.com/blog/kzg-batch-proof.html) notes (kind of the continuation of the current notes).
|
||||
|
||||
As a final note, in order to try to digest the notes, I've did a *toy implementation* of this scheme at https://github.com/arnaucube/kzg-commitments-study. It's quite simple, but contains the logic overviewed in this notes.
|
||||
|
||||
|
||||
307
blogo-input/posts/powersoftau.md
Normal file
@@ -0,0 +1,307 @@
|
||||
# Implementing the powers of tau contributor
|
||||
*2023-01-02*
|
||||
|
||||
In the following notes we go over the ideas behind the *Powers of Tau* ceremony, how participants contribute and how the contributions are verified.
|
||||
|
||||
The powers of tau are used in schemes such as KZG Commitments, and by consequence in the Plonk-KZG and in Verkle Trees use cases, which the later ones are in the Ethereum roadmap, but probably the ceremony output will be used in many other applications.
|
||||
The ceremony is named also as *Trusted Setup Ceremony*, and *SRS* (Structured Reference String) in Plonk and Sonic papers.
|
||||
|
||||
Specifically these notes focus on the powers of tau ceremony that is [being prepared in Ethereum](https://github.com/ethereum/kzg-ceremony). For learning about the specifics of the powers of tau reasoning, I've used the following two documents:
|
||||
|
||||
- [KZG10-Ceremony-audit-report.pdf, by SECBIT Labs](https://github.com/ethereum/kzg-ceremony/blob/main/KZG10-Ceremony-audit-report.pdf)
|
||||
- [*Why and how zkSNARKs work*, by Maksym Petkus](https://arxiv.org/abs/1906.07221v1)
|
||||
|
||||
Additionally, [this article by Vitalik Buterin](https://vitalik.ca/general/2022/03/14/trustedsetup.html) explains the ideas behind trusted setups.
|
||||
|
||||
The contents of these notes are distributed as follows:
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#the-main idea">The main idea</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#preliminaries">Preliminaries</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#participant-contribution">Participant contribution</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#proof-of correct computation">Proof of correct computation</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#contribution-verification">Contribution verification</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#full-flow">Full flow</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#conclusions">Conclusions</a>
|
||||
|
||||
Across these notes some snippets of Sage code are provided, the full Sage code can be found [here](https://github.com/arnaucube/math/blob/master/powersoftau.sage), and also a [full implementation in Go](https://github.com/arnaucube/eth-kzg-ceremony-alt) which also contains a CLI to participate in the upcomming Ethereum KZG-Ceremony.
|
||||
|
||||
|
||||
### The main idea
|
||||
The main idea is that we want to compute $\tau^0, \tau^1, \tau^2, \ldots, \tau^{n-1}$, where $\tau$ should be unknown. In order to achieve this, we use some technics to combine different $\tau$s from different contributors, in a way where we obtain the powers of a tau which is a combination of the different secret taus ($\tau_{p_i}$) of the different participants.
|
||||
|
||||
The $\tau_{p_i}$ should be secret for each participant, furthermore, it should be generated from some source of randomness and destroyed at the end.
|
||||
|
||||
As we've mentioned, we want to come up with the powers of tau where tau is a combination of the taus from all the participants, in a way where as long as there is at least one honest participant, which does not share their part of the final tau, the combined-tau can not be recovered and the ceremony is assumed to be safe.
|
||||
|
||||
This is important, because if somebody has knowledge of the tau value, could generate fake proofs. As an example [this article by Kobi Gurkan](https://medium.com/qed-it/how-toxic-is-the-waste-in-a-zksnark-trusted-setup-9b250d59bdb4) shows how fake BCTV14a proofs can be generated if tau is known.
|
||||
|
||||
This is relevant in the context of [KZG Commitments](https://arnaucube.com/blog/kzg-commitments.html), specially in the roadmap of Ethereum.
|
||||
Ethereum will run the Ceremony which will be used at least in [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844). That's why EF's is encouraging people to participate in various ways, as the Ceremony is considered safe as long as there is at least one honest participant, with the idea that if you participate, assuming that you consider yourself honest, you can consider the Ceremony safe.
|
||||
|
||||
The output of the ceremony will be used in the Ethereum VerkleTrees, which uses KZG Commitments, but also it will be useful for Plonk-KZG proofs.
|
||||
|
||||
So the best way to trust the output of the ceremony is by becoming a participant yourself!, Furhermore, by participating with your own code ^^
|
||||
|
||||
### Preliminaries
|
||||
|
||||
**Pairing**<br>
|
||||
We will try to focus only in the concepts that we strictly need for the implementation, so we will treat Pairings as a black box with some simplified properties.
|
||||
|
||||
For our use case, we use asymmetric bilinear pairings. We can see an asymmetric bilinear pairing as a function that maps an element from the group $\mathbb{G_1}$ and another one from $\mathbb{G_2}$ into an el element of the group $\mathbb{G_T}$.
|
||||
|
||||
$$e: \mathbb{G_1} \times \mathbb{G_2} \longrightarrow \mathbb{G_T}$$
|
||||
|
||||
For our use case, we'll focus only on one property, *bilinearity*.
|
||||
|
||||
Let $a, b \in \mathbb{F_q}$, $\mathbb{G}_1 = \langle G \rangle$ and $\mathbb{G}_2 = \langle H \rangle~$ (In other words, $G$ is the generator of $\mathbb{G}_1$, and $H$ is the generator of $\mathbb{G}_2$).
|
||||
|
||||
Then, the bilinearity property tells us that
|
||||
|
||||
$$e(a \cdot G,~b \cdot H) = e((a \cdot b) \cdot G,~H) = e(G,~(a \cdot b) \cdot H)$$
|
||||
|
||||
For better readability, we will use the following notation to represent the scalar point multiplication:
|
||||
|
||||
$$[x]_1 = x \cdot G \in \mathbb{G}_1\newline
|
||||
[x]_2 = x \cdot H \in \mathbb{G}_2$$
|
||||
|
||||
So, our previous bilinearity example would look like
|
||||
|
||||
$$e([a]_1, [b]_2) = e([a \cdot b]_1, [1]_2) = e([1]_1, [a \cdot b]_2)$$
|
||||
|
||||
In our practical use case, we use the [BLS12-381](https://hackmd.io/@benjaminion/bls12-381) pairing, where $\mathbb{G}_1, \mathbb{G}_2$ are elliptic curve groups, thus the points $G, H$ are elliptic curve points.
|
||||
|
||||
**Code**<br>
|
||||
For the code examples we'll use [SageMath](https://www.sagemath.org), but the code would look quite similar in Python, and the same logic can be implemented in any language.
|
||||
|
||||
|
||||
### Participant contribution
|
||||
In the context of SRS (Structured Reference String), the powers of tau consist of an array containing the scalar multiplication of the generator point by each power of tau, eg. $\tau^0 \cdot G,~\tau^1 \cdot G,~\tau^2 \cdot G,~\tau^3 \cdot G \ldots$
|
||||
|
||||
For our case, we'll generate $n$ powers of tau on $\mathbb{G}_1$, and $m$ on $\mathbb{G}_2$. We will denote the combination of both $\mathbb{G}_1$ and $\mathbb{G}_2$ powers of tau by SRS.
|
||||
|
||||
Each participant will obtain the previous-participant generated SRS, which is formed by
|
||||
|
||||
$$\{ [\tau^0]_1, [\tau^1]_1, [\tau^2]_2, \ldots, [\tau^{n-1}]_1 \},\\
|
||||
\{ [\tau^0]_2, [\tau^1]_2, [\tau^2]_2, \ldots, [\tau^{m-1}]_2 \}$$
|
||||
|
||||
for simplicity, we will represent it as
|
||||
|
||||
$$\{~[~\tau^i]_1~\}^{n-1}_{i=0},~\{~[~\tau^i]_2~\}^{m-1}_{j=0}$$
|
||||
|
||||
|
||||
Each participant generates their secret random tau $\tau_p$, which to avoid confusion we will denote as $p \in \mathbb{F}_r$. From it, the participant can compute $[p]_2 \in \mathbb{G}_2$.
|
||||
|
||||
Then the participant proceeds to update the reference string (SRS), by multiplying each element by $p^i$:
|
||||
|
||||
$$\{~ p^i \cdot [~ \tau^i]_1~\}^{n-1}_{i=0},~\{~ p^i \cdot [~\tau^i]_2~\}^{m-1}_{j=0}$$
|
||||
|
||||
which, by the properties of scalar multiplication of a point, is equivalent to
|
||||
|
||||
$$\{~ [~ (p \cdot \tau)^i]_1~\}^{n-1}_{i=0},~\{~ [~ (p \cdot \tau)^i]_2~\}^{m-1}_{j=0}$$
|
||||
|
||||
and we denote $p \cdot \tau$ as $\tau'$, so we can write the previous expression as
|
||||
|
||||
$$\{~[~\tau'^i]_1~\}^{n-1}_{i=0},~\{~[~\tau'^i]_2~\}^{m-1}_{j=0}$$
|
||||
|
||||
which is
|
||||
|
||||
$$\{ [(\tau \cdot p)^0]_1, [(\tau \cdot p)^1]_1, [(\tau \cdot p)^2]_2, \ldots, [(\tau \cdot p)^{n-1}]_1 \},\\
|
||||
\{ [(\tau \cdot p)^0]_2, [(\tau \cdot p)^1]_2, [(\tau \cdot p)^2]_2, \ldots, [(\tau \cdot p)^{m-1}]_2 \}$$
|
||||
|
||||
Notice that the contributor does not know the previous $\tau$, but can obtain $(\tau \cdot p)^i$.
|
||||
|
||||
<br><br>
|
||||
We can express the previous logic as follows:
|
||||
|
||||
```python
|
||||
def compute_contribution(new_tau, prev_srs):
|
||||
g1s = [None] * len(prev_srs[0])
|
||||
g2s = [None] * len(prev_srs[1])
|
||||
srs = [g1s, g2s]
|
||||
Q = e.r
|
||||
|
||||
# compute [τ'⁰]₁, [τ'¹]₁, [τ'²]₁, ..., [τ'ⁿ⁻¹]₁, where n = len(prev_srs.G1s)
|
||||
for i in range(0, len(prev_srs[0])):
|
||||
srs[0][i] = (new_tau^i) * prev_srs[0][i]
|
||||
|
||||
# compute [τ'⁰]₂, [τ'¹]₂, [τ'²]₂, ..., [τ'ⁿ⁻¹]₂, where n = len(prev_srs.G2s)
|
||||
for i in range(0, len(prev_srs[1])):
|
||||
srs[1][i] = (new_tau^i) * prev_srs[1][i]
|
||||
|
||||
return srs
|
||||
```
|
||||
|
||||
### Proof of correct computation
|
||||
The participant will compute the proof, which consists of
|
||||
|
||||
$$\pi = ([\tau']_1,~[p]_2)$$
|
||||
|
||||
which is equivalent to $\pi = (\tau' \cdot G,~p \cdot H) = ((p \cdot \tau) \cdot G,~p \cdot H)$
|
||||
|
||||
In the next section we will see how this is used to verify the contribution correct computation.
|
||||
|
||||
<br>
|
||||
We implement this logic as follows:
|
||||
|
||||
```python
|
||||
def generate_proof(tau, prev_srs, new_srs):
|
||||
# g_1^{tau'} = g_1^{p * tau} = SRS_G1s[1] * p
|
||||
g1_ptau = prev_srs[0][1] * tau
|
||||
# g_2^{p}
|
||||
g2_p = tau * e.G2
|
||||
return [g1_ptau, g2_p]
|
||||
```
|
||||
|
||||
### Contribution verification
|
||||
This is the interesting part. We want to check that the new SRS is well computed from the previous SRS together with the new tau. We want to avoid accepting contributions that do not follow the powers of tau structure, or that contain empty elements or that do not derive from the previous SRS.
|
||||
|
||||
Following the powers of tau structure means that
|
||||
|
||||
$$\tau'^{i+1} = \tau' \cdot \tau'^i ~~\forall~i \in [1, n-1]$$
|
||||
|
||||
And the relation between the new SRS and the previous SRS is
|
||||
|
||||
$$\tau' = \tau \cdot p$$
|
||||
where $\tau$ is the secret element from the previous SRS and $p$ is the secret one from the new SRS, resulting in the combined $\tau'$.
|
||||
|
||||
Now, we're interested into how we can check these relations in the context of the SRS elements. A new contribution can be verified as follows:
|
||||
|
||||
1. Check that elements of the new SRS are non-empty, non-zero and in the correct prime order subgroups.
|
||||
2. Get the proof ($\pi = ([\tau']_1, [p]_2)$), and confirm that the 1st element is equal to the element in position 1 $[\tau'^1]_1$ of the new SRS (which corresponds to $\tau'$ powered to $1$).
|
||||
|
||||
3. Check that $\tau'$ (the new SRS) is correctly related to $\tau$ (the previous SRS).
|
||||
|
||||
To check this, we rely on the pairing properties and we use the proof value generated by the contributor, which consists of $[p]_2$
|
||||
|
||||
$$e([\tau]_1, [p]_2) \stackrel{?}{=} e([\tau']_1, [1]_2)$$
|
||||
|
||||
We can see how this holds, as $\tau' = p \cdot \tau$, and by the bilinear property of the pairing (see [Preliminearies section](#preliminaries)) we have $e(a \cdot G, b \cdot H) = e((a \cdot b) \cdot G, H)$, which in our notation is represented as
|
||||
|
||||
$$e([a]_1, [b]_2) = e([a \cdot b]_1, [1]_2)$$
|
||||
|
||||
by applying this to our case we can see that:
|
||||
|
||||
$$e([\tau]_1, [p]_2) = e([\tau \cdot p]_1, [1]_2) = e([\tau']_1, [1]_2)$$
|
||||
|
||||
4. Check if the new SRS follows the powers of tau structure:
|
||||
|
||||
$$e([\tau'^i]_1, [\tau']_2) \stackrel{?}{=} e([\tau'^{i+1}]_1, [1]_2) ~~ \forall ~i \in [1, n-1]$$
|
||||
$$e([\tau']_1, [\tau'^j]_2) \stackrel{?}{=} e([1]_1, [\tau'^{j+1}]_2) ~~ \forall ~i \in [1, m-1]$$
|
||||
|
||||
Which, again, by the bilinarity property, we can see that
|
||||
|
||||
$$e([\tau'^i]_1, [\tau']_2) = e([\tau'^{i+1}]_1, [1]_2)$$
|
||||
|
||||
is enforcing that $\tau'^i \cdot \tau'^1 = \tau'^{i+1}$.
|
||||
|
||||
And the same for
|
||||
|
||||
$$e([\tau']_1, [\tau'^j]_2) = e([1]_1, [\tau'^{j+1}]_2)$$
|
||||
|
||||
which checks that $\tau'^1 \cdot \tau'^j = \tau'^{j+1}$.
|
||||
|
||||
With this check, we're ensuring that each power of tau of the SRS is consistent with the previous one.
|
||||
|
||||
|
||||
<br><br>
|
||||
The complete verification function would look like
|
||||
|
||||
```python
|
||||
def verify(prev_srs, new_srs, proof):
|
||||
# 1. check that elements of the newSRS are valid points
|
||||
for i in range(0, len(new_srs[0])-1):
|
||||
assert new_srs[0][i] != None
|
||||
assert new_srs[0][i] != e.E1(0)
|
||||
assert new_srs[0][i] in e.E1
|
||||
for i in range(0, len(new_srs[1])-1):
|
||||
assert new_srs[1][i] != None
|
||||
assert new_srs[1][i] != e.E1(0)
|
||||
assert new_srs[1][i] in e.E2
|
||||
|
||||
# 2. check proof.G1PTau == newSRS.G1Powers[1]
|
||||
assert proof[0] == new_srs[0][1]
|
||||
|
||||
# 3. check newSRS.G1s[1] (g₁^τ'), is correctly related to prev_srs.G1s[1] (g₁^τ)
|
||||
# e([τ]₁, [p]₂) == e([τ']₁, [1]₂)
|
||||
assert e.pair(prev_srs[0][1], proof[1]) == e.pair(new_srs[0][1], e.G2)
|
||||
|
||||
# 4. check newSRS following the powers of tau structure
|
||||
# i) e([τ'ⁱ]₁, [τ']₂) == e([τ'ⁱ⁺¹]₁, [1]₂), for i ∈ [1, n−1]
|
||||
for i in range(0, len(new_srs[0])-1):
|
||||
assert e.pair(new_srs[0][i], new_srs[1][1]) == e.pair(new_srs[0][i+1], e.G2)
|
||||
|
||||
# ii) e([τ']₁, [τ'ʲ]₂) == e([1]₁, [τ'ʲ⁺¹]₂), for j ∈ [1, m−1]
|
||||
for i in range(0, len(new_srs[1])-1):
|
||||
assert e.pair(new_srs[0][1], new_srs[1][i]) == e.pair(e.G1, new_srs[1][i+1])
|
||||
```
|
||||
|
||||
|
||||
### Full flow
|
||||
Now that we have the three methods (*compute_contribution, generate_proof, verify*), it's a matter of using them.
|
||||
|
||||
First let's add a couple of helpers to our code:
|
||||
```python
|
||||
# here we import the BLS12-381 pairing machinery
|
||||
load("bls12-381.sage") # file from https://github.com/arnaucube/math/blob/master/bls12-381.sage
|
||||
e = Pairing()
|
||||
|
||||
# this method generates a SRS filled by the generator points of G1 & G2
|
||||
def new_empty_SRS(nG1, nG2):
|
||||
g1s = [None] * nG1
|
||||
g2s = [None] * nG2
|
||||
for i in range(0, nG1):
|
||||
g1s[i] = e.G1
|
||||
for i in range(0, nG2):
|
||||
g2s[i] = e.G2
|
||||
|
||||
return [g1s, g2s]
|
||||
```
|
||||
|
||||
Let's do the flow:
|
||||
```python
|
||||
# generate a fake previous-SRS
|
||||
(prev_srs) = new_empty_SRS(5, 3)
|
||||
|
||||
# set a random value to be used for our tau
|
||||
random = 12345 # this would be a random value
|
||||
tau = e.F1(random)
|
||||
|
||||
# compute our contribution, from the previous SRS and our tau
|
||||
new_srs = compute_contribution(tau, prev_srs)
|
||||
|
||||
# generate a proof of correct computation of our contribution
|
||||
proof = generate_proof(tau, prev_srs, new_srs)
|
||||
|
||||
# verify the proof for the given prev_srs and the new_srs
|
||||
verify(prev_srs, new_srs, proof)
|
||||
```
|
||||
|
||||
## Conclusions
|
||||
|
||||
As we've seen, we can prove and verify the correct computation of the new SRS with few operations.
|
||||
|
||||
From here the next thing would be to implement the [interaction with the Sequencer](https://github.com/ethereum/kzg-ceremony-specs/blob/master/apiSpec/sequencerApi.yml), in order to authenticate the participant, fetch the previous SRS, and send the new SRS and proof.
|
||||
|
||||
You can find the Sage example that we've been using [here](https://github.com/arnaucube/math/blob/master/powersoftau.sage), and a full Go implementation here: https://github.com/arnaucube/eth-kzg-ceremony-alt (which uses [Kilic's BLS12-381 implementation](https://github.com/kilic/bls12-381), and includes also the interaction with the Sequencer and a CLI).
|
||||
There is also the EF's rust implementation [small-powers-of-tau](https://github.com/crate-crypto/small-powers-of-tau) which has been audited. The same logic can be implemented in the language of your choice.
|
||||
<br><br>
|
||||
|
||||
<a href="https://github.com/arnaucube/eth-kzg-ceremony-alt" target="_blank" title="https://github.com/arnaucube/eth-kzg-ceremony-alt">
|
||||
<img src="img/posts/powersoftau/kzg-ceremony-screenshot.png" style="width:100%;" />
|
||||
<span style="font-size:80%; color:gray;font-style:italic;">Screenshot of the eth-kzg-ceremony-alt CLI after contributing to the testnet ceremony.</a>
|
||||
</a>
|
||||
|
||||
|
||||
Another interesting piece is the *randomness generation*. In our example, for simplicity, tau was hardcoded in the code, but in the real world case we would use some source of randomness to generate our secret value. Here you can get [as creative as you can](https://www.youtube.com/watch?v=I4cDAqeEmpU), and probably we will see some cool approaches for the Ethereum-KZG-Ceremony.
|
||||
|
||||
This ceremony output is quite important, as it will be used in many applications once available. It will be used in the Ethereum protocol for the KZG Commitments on EIP-4844, but also on many other applications (some of them unrelated to Ethereum!). For example, any (up to the degree upperbound) Plonk-KZG deployment could reuse this ceremony to avoid needing to compute their own.
|
||||
So it's important to gather a notable amount of participants in the ceremony, and probably participate to it by yourself! (as if you're contributing you know that at least there has been one honest contribution (you)).
|
||||
|
||||
You can find more info on the Ethereum's KZG Ceremony here: https://ceremony.ethereum.org (which includes also a nice contributor webapp to participate from the browser).
|
||||
|
||||
5
blogo-input/posts/powersoftau_thumb.md
Normal file
@@ -0,0 +1,5 @@
|
||||
### Implementing the powers of tau contributor
|
||||
|
||||
In the following notes we go over the ideas behind the *Powers of Tau* ceremony, how participants contribute and how the contributions are verified (logic & code). We focus on the Ethereum's upcoming KZG-Ceremony.
|
||||
|
||||
*2023-01-02*
|
||||
165
blogo-input/posts/ringsig.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# bLSAG ring signatures overview
|
||||
*2022-07-20*
|
||||
|
||||
> Note: I’m not a mathematician, I’m just an amateur on math. These notes are just an attempt to try to sort the notes that I took while learning abut bLSAG.
|
||||
|
||||
<br>
|
||||
bLSAG: Back's Linkable Spontaneous Anonymous Group signatures
|
||||
|
||||
- signer ambiguity
|
||||
- linkability
|
||||
- unforgeability
|
||||
|
||||
### Setup
|
||||
Let $G$ be the generator of an EC group.
|
||||
We use a hash function $\mathcal{H}_p$, which maps to curve points in EC, and a normal hash $\mathcal{H}_n$, which maps to $\mathbb{Z}_p$.
|
||||
Signer's key pair: $k_{\pi}$, s.t. $K_{\pi} = k_{\pi} \cdot G \in \mathcal{R}$, with secret index $\pi$.
|
||||
Set of Public Keys: $\mathcal{R} = \{ K_1, K_2, \ldots, K_n \}$
|
||||
|
||||
```python
|
||||
def new_key():
|
||||
k = F.random_element()
|
||||
K = g * k # g is the generator of the EC group
|
||||
return K
|
||||
```
|
||||
|
||||
### Signature
|
||||
1. compute key image: $\tilde{K} = k_{\pi} \mathcal{H_p} ( K_{\pi}) \in G$
|
||||
```python
|
||||
key_image = k * hashToPoint(K)
|
||||
```
|
||||
|
||||
2. Generate $\alpha \in^R \mathbb{Z}_p$, and $r_i \in^R \mathbb{Z}_p$, for $i \in \{1, 2, \ldots, n \}$, with $i \neq \pi$
|
||||
- $r_i$ is used for the fake responses
|
||||
```python
|
||||
a = F.random_element()
|
||||
r = [None] * len(R)
|
||||
for i in range(0, len(R)):
|
||||
if i==pi:
|
||||
continue
|
||||
|
||||
r[i] = mod(F.random_element(), p)
|
||||
```
|
||||
|
||||
3. Compute $c_{\pi + 1} = \mathcal{H}_n ( m, [\alpha G], [\alpha \mathcal{H}_p(K_{\pi})])$
|
||||
|
||||
```python
|
||||
c[pi1] = hash(R, m, a * g, hashToPoint(R[pi]) * a, p)
|
||||
```
|
||||
|
||||
4. for $i=\pi + 1, \pi +2, \ldots, n, 1, 2, \ldots, \pi -1$, calculate, replacing $n+1 \rightarrow 1$
|
||||
$$
|
||||
c_{i+1} = \mathcal{H}_n (m, [r_i G + c_i K_i], [r_i \mathcal{H}_p (K_i) + c_i \tilde{K}])
|
||||
$$
|
||||
- Notice that (from step 3 & 4):<br>
|
||||
$\alpha \mathcal{H}_p (K_{\pi}) = r_{\pi} \mathcal{H}_p (K_{\pi}) + c_{\pi} \cdot (\tilde{K})$,<br>
|
||||
where $\tilde{K}= k_{\pi} \mathcal{H_p} ( K_{\pi})$, so:<br>
|
||||
$\alpha \mathcal{H}_p (K_{\pi}) = r_{\pi} \mathcal{H}_p (K_{\pi}) + c_{\pi} \cdot (k_{\pi} \mathcal{H}_p(K_{\pi}))$<br>
|
||||
which is equal to,<br>
|
||||
$\alpha \cdot \mathcal{H}_p (K_{\pi}) = (r_{\pi} + c_{\pi} \cdot k_{\pi}) \cdot \mathcal{H}_p(K_{\pi})$<br>
|
||||
From where we can see: $\alpha = r_{\pi} + c_{\pi} \cdot k_{\pi}$<br>
|
||||
which we can rearrange to
|
||||
$r_{\pi} = \alpha - c_{\pi} \cdot k_{\pi}$.<br><br>
|
||||
|
||||
```python
|
||||
for j in range(0, len(R)-1):
|
||||
i = mod(pi1+j, len(R))
|
||||
i1 = mod(pi1+j +1, len(R))
|
||||
|
||||
c[i1] = hash(R, m, r[i] * g + c[i] * R[i],
|
||||
r[i] * hashToPoint(R[i]) + c[i] * key_image, p)
|
||||
```
|
||||
|
||||
6. Define $r_{\pi} = \alpha - c_{\pi} k_{\pi} \mod{p}$
|
||||
|
||||
```python
|
||||
r[pi] = mod(a - c[pi] * k, p)
|
||||
```
|
||||
|
||||
Signature: $\sigma(m) = (c_1, r_1, \ldots, r_n)$, with key image $\tilde{K}$ and ring $\mathcal{R}$.
|
||||
- $len(\sigma(m)) = 1+n$
|
||||
|
||||
```python
|
||||
return [c[0], r]
|
||||
```
|
||||
|
||||
|
||||
<br><br><br>
|
||||
|
||||
#### Step by step (simplified):
|
||||
|
||||
<div style="overflow:auto;">
|
||||
<div style="width: 60%; float:left; height: 360px; overflow-y:scroll;">
|
||||
|
||||
<img src="img/posts/ring-sig/step00.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step00.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step01.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step02.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step03.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step04.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step05.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step06.png" style="width:100%;" />
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div style="width: 40%; float:right; margin-top:80px;">
|
||||
|
||||
<ul>
|
||||
<li>Generate $r_i \in^R \mathbb{Z_p}$</li>
|
||||
<li>Compute $c_{i+1}$ from $r_i$</li>
|
||||
<li>Link $r_{\pi}$ with $c_{\pi}$</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
*You can scroll down the images through the step-by-step diagrams.*
|
||||
|
||||
<br>
|
||||
|
||||
It reminds in some way to the approach to close a box like the one in the picture:
|
||||

|
||||
|
||||
|
||||
<br><br><br>
|
||||
### Verification
|
||||
1. check $p \tilde{K} \stackrel{?}{=} 0$
|
||||
- to ensure that $\tilde{K} \in G$ (and not in a cofactor group of $G$)
|
||||
2. for $i = 1, 2, \ldots, n$, replacing $n+1 \rightarrow 1$
|
||||
$$
|
||||
c'_{i+1} = \mathcal{H}_n (m, [r_i G + c_i K_i], [r_i \mathcal{H}_p (K_i) + c_i \tilde{K}])
|
||||
$$
|
||||
3. check $c_1 \stackrel{?}{=} c'_i$
|
||||
```python
|
||||
c[0] = c1
|
||||
for j in range(0, len(R)):
|
||||
i = mod(j, len(R))
|
||||
i1 = mod(j+1, len(R))
|
||||
c[i1] = hash(R, m, r[i] * g + c[i] * R[i],
|
||||
r[i] * hashToPoint(R[i]) + c[i] * key_image, p)
|
||||
|
||||
assert c1 == c[0]
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
## Links
|
||||
Toy implementation:
|
||||
|
||||
- Sage: https://github.com/arnaucube/math/blob/master/ring-signatures.sage
|
||||
- Rust: https://github.com/arnaucube/ring-signatures-rs
|
||||
|
||||
Resources:
|
||||
|
||||
- *"Zero to Monero"* - https://web.getmonero.org/library/Zero-to-Monero-2-0-0.pdf
|
||||
(section *"3.4 Back’s Linkable Spontaneous Anonymous Group (bLSAG) signatures"*)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
4
blogo-input/posts/ringsig_thumb.md
Normal file
@@ -0,0 +1,4 @@
|
||||
### bLSAG ring signatures overview
|
||||
Notes on bLSAG: Back's Linkable Spontaneous Anonymous Group signatures
|
||||
|
||||
*2022-07-20*
|
||||
@@ -19,6 +19,8 @@
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -26,7 +28,8 @@
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css">
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
@@ -39,7 +42,11 @@
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<a href="/blog" style="color:#000;">Blog index</a>
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
@@ -164,6 +171,9 @@ func main() {
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
@@ -233,7 +243,7 @@ func main() {
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -26,7 +28,8 @@
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css">
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
@@ -39,7 +42,11 @@
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<a href="/blog" style="color:#000;">Blog index</a>
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
@@ -413,6 +420,9 @@ func putHTMLToTemplate(template string, m map[string]string) string {
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
@@ -482,7 +492,7 @@ func putHTMLToTemplate(template string, m map[string]string) string {
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -26,7 +28,8 @@
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css">
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
@@ -39,7 +42,11 @@
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<a href="/blog" style="color:#000;">Blog index</a>
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
@@ -552,6 +559,9 @@ def start():
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
@@ -621,7 +631,7 @@ def start():
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
|
||||
@@ -12,10 +12,16 @@ body {
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
.dark-theme img, .dark-theme video, .dark-theme iframe, .dark-theme .onoffswitch-label, .dark-theme code {
|
||||
/* .dark-theme img, .dark-theme video, .dark-theme iframe, .dark-theme .onoffswitch-label, .dark-theme code { */
|
||||
.dark-theme img, .dark-theme video, .dark-theme iframe, .dark-theme .onoffswitch-label {
|
||||
filter: invert(100%) hue-rotate(180deg);
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #fafafa;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration:none!important;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -26,7 +28,8 @@
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css">
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
@@ -39,7 +42,11 @@
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<a href="/blog" style="color:#000;">Blog index</a>
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
@@ -338,6 +345,9 @@
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
@@ -407,7 +417,7 @@
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
|
||||
BIN
public/img/posts/powersoftau/kzg-ceremony-screenshot.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
public/img/posts/ring-sig/box-closed.png
Normal file
|
After Width: | Height: | Size: 255 KiB |
BIN
public/img/posts/ring-sig/step00.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
public/img/posts/ring-sig/step01.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
public/img/posts/ring-sig/step02.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
public/img/posts/ring-sig/step03.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
public/img/posts/ring-sig/step04.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
public/img/posts/ring-sig/step05.png
Normal file
|
After Width: | Height: | Size: 138 KiB |
BIN
public/img/posts/ring-sig/step06.png
Normal file
|
After Width: | Height: | Size: 163 KiB |
@@ -19,6 +19,8 @@
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -26,7 +28,8 @@
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css">
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
@@ -39,7 +42,11 @@
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<a href="/blog" style="color:#000;">Blog index</a>
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
@@ -55,7 +62,25 @@
|
||||
|
||||
|
||||
<div class="container" style="margin-top:40px;max-width:800px;">
|
||||
<a href='/blog/shamir-secret-sharing.html'><div class="row postThumb">
|
||||
<a href='/blog/powersoftau.html'><div class="row postThumb">
|
||||
<h3>Implementing the powers of tau contributor</h3>
|
||||
|
||||
<p>In the following notes we go over the ideas behind the <em>Powers of Tau</em> ceremony, how participants contribute and how the contributions are verified (logic & code). We focus on the Ethereum’s upcoming KZG-Ceremony.</p>
|
||||
|
||||
<p><em>2023-01-02</em></p>
|
||||
|
||||
</div>
|
||||
|
||||
</a><a href='/blog/ringsig.html'><div class="row postThumb">
|
||||
<h3>bLSAG ring signatures overview</h3>
|
||||
|
||||
<p>Notes on bLSAG: Back’s Linkable Spontaneous Anonymous Group signatures</p>
|
||||
|
||||
<p><em>2022-07-20</em></p>
|
||||
|
||||
</div>
|
||||
|
||||
</a><a href='/blog/shamir-secret-sharing.html'><div class="row postThumb">
|
||||
<h3>Lagrange Polynomial Interpolation and Shamir secret sharing</h3>
|
||||
|
||||
<p>Overview of Langrange Polynomial interpolation and Shamir’s secret sharing.</p>
|
||||
@@ -123,6 +148,9 @@
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
@@ -192,7 +220,7 @@
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
|
||||
133
public/js/drawdown.js
Normal file
@@ -0,0 +1,133 @@
|
||||
// Code from the repo: https://github.com/adamvleggett/drawdown
|
||||
//
|
||||
|
||||
/**
|
||||
* drawdown.js
|
||||
* (c) Adam Leggett
|
||||
*/
|
||||
|
||||
|
||||
;function markdown(src) {
|
||||
|
||||
var rx_lt = /</g;
|
||||
var rx_gt = />/g;
|
||||
var rx_space = /\t|\r|\uf8ff/g;
|
||||
var rx_escape = /\\([\\\|`*_{}\[\]()#+\-~])/g;
|
||||
var rx_hr = /^([*\-=_] *){3,}$/gm;
|
||||
var rx_blockquote = /\n *> *([^]*?)(?=(\n|$){2})/g;
|
||||
var rx_list = /\n( *)(?:[*\-+]|((\d+)|([a-z])|[A-Z])[.)]) +([^]*?)(?=(\n|$){2})/g;
|
||||
var rx_listjoin = /<\/(ol|ul)>\n\n<\1>/g;
|
||||
var rx_highlight = /(^|[^A-Za-z\d\\])(([*_])|(~)|(\^)|(--)|(\+\+)|`)(\2?)([^<]*?)\2\8(?!\2)(?=\W|_|$)/g;
|
||||
var rx_code = /\n((```|~~~).*\n?([^]*?)\n?\2|(( .*?\n)+))/g;
|
||||
var rx_link = /((!?)\[(.*?)\]\((.*?)( ".*")?\)|\\([\\`*_{}\[\]()#+\-.!~]))/g;
|
||||
var rx_table = /\n(( *\|.*?\| *\n)+)/g;
|
||||
var rx_thead = /^.*\n( *\|( *\:?-+\:?-+\:? *\|)* *\n|)/;
|
||||
var rx_row = /.*\n/g;
|
||||
var rx_cell = /\||(.*?[^\\])\|/g;
|
||||
var rx_heading = /(?=^|>|\n)([>\s]*?)(#{1,6}) (.*?)( #*)? *(?=\n|$)/g;
|
||||
var rx_para = /(?=^|>|\n)\s*\n+([^<]+?)\n+\s*(?=\n|<|$)/g;
|
||||
var rx_stash = /-\d+\uf8ff/g;
|
||||
|
||||
function replace(rex, fn) {
|
||||
src = src.replace(rex, fn);
|
||||
}
|
||||
|
||||
function element(tag, content) {
|
||||
return '<' + tag + '>' + content + '</' + tag + '>';
|
||||
}
|
||||
|
||||
function blockquote(src) {
|
||||
return src.replace(rx_blockquote, function(all, content) {
|
||||
return element('blockquote', blockquote(highlight(content.replace(/^ *> */gm, ''))));
|
||||
});
|
||||
}
|
||||
|
||||
function list(src) {
|
||||
return src.replace(rx_list, function(all, ind, ol, num, low, content) {
|
||||
var entry = element('li', highlight(content.split(
|
||||
RegExp('\n ?' + ind + '(?:(?:\\d+|[a-zA-Z])[.)]|[*\\-+]) +', 'g')).map(list).join('</li><li>')));
|
||||
|
||||
return '\n' + (ol
|
||||
? '<ol start="' + (num
|
||||
? ol + '">'
|
||||
: parseInt(ol,36) - 9 + '" style="list-style-type:' + (low ? 'low' : 'upp') + 'er-alpha">') + entry + '</ol>'
|
||||
: element('ul', entry));
|
||||
});
|
||||
}
|
||||
|
||||
function highlight(src) {
|
||||
return src.replace(rx_highlight, function(all, _, p1, emp, sub, sup, small, big, p2, content) {
|
||||
return _ + element(
|
||||
emp ? (p2 ? 'strong' : 'em')
|
||||
: sub ? (p2 ? 's' : 'sub')
|
||||
: sup ? 'sup'
|
||||
: small ? 'small'
|
||||
: big ? 'big'
|
||||
: 'code',
|
||||
highlight(content));
|
||||
});
|
||||
}
|
||||
|
||||
function unesc(str) {
|
||||
return str.replace(rx_escape, '$1');
|
||||
}
|
||||
|
||||
var stash = [];
|
||||
var si = 0;
|
||||
|
||||
src = '\n' + src + '\n';
|
||||
|
||||
replace(rx_lt, '<');
|
||||
replace(rx_gt, '>');
|
||||
replace(rx_space, ' ');
|
||||
|
||||
// blockquote
|
||||
src = blockquote(src);
|
||||
|
||||
// horizontal rule
|
||||
replace(rx_hr, '<hr/>');
|
||||
|
||||
// list
|
||||
src = list(src);
|
||||
replace(rx_listjoin, '');
|
||||
|
||||
// code
|
||||
replace(rx_code, function(all, p1, p2, p3, p4) {
|
||||
stash[--si] = element('pre', element('code', p3||p4.replace(/^ /gm, '')));
|
||||
return si + '\uf8ff';
|
||||
});
|
||||
|
||||
// link or image
|
||||
replace(rx_link, function(all, p1, p2, p3, p4, p5, p6) {
|
||||
stash[--si] = p4
|
||||
? p2
|
||||
? '<img src="' + p4 + '" alt="' + p3 + '"/>'
|
||||
: '<a href="' + p4 + '">' + unesc(highlight(p3)) + '</a>'
|
||||
: p6;
|
||||
return si + '\uf8ff';
|
||||
});
|
||||
|
||||
// table
|
||||
replace(rx_table, function(all, table) {
|
||||
var sep = table.match(rx_thead)[1];
|
||||
return '\n' + element('table',
|
||||
table.replace(rx_row, function(row, ri) {
|
||||
return row == sep ? '' : element('tr', row.replace(rx_cell, function(all, cell, ci) {
|
||||
return ci ? element(sep && !ri ? 'th' : 'td', unesc(highlight(cell || ''))) : ''
|
||||
}))
|
||||
})
|
||||
)
|
||||
});
|
||||
|
||||
// heading
|
||||
replace(rx_heading, function(all, _, p1, p2) { return _ + element('h' + p1.length, unesc(highlight(p2))) });
|
||||
|
||||
// paragraph
|
||||
replace(rx_para, function(all, content) { return element('p', unesc(highlight(content))) });
|
||||
|
||||
// stash
|
||||
replace(rx_stash, function(all) { return stash[parseInt(all)] });
|
||||
|
||||
return src.trim();
|
||||
};
|
||||
|
||||
94
public/js/highlightjs/atom-one-light.css
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
|
||||
Atom One Light by Daniel Gamage
|
||||
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
|
||||
|
||||
base: #fafafa
|
||||
mono-1: #383a42
|
||||
mono-2: #686b77
|
||||
mono-3: #a0a1a7
|
||||
hue-1: #0184bb
|
||||
hue-2: #4078f2
|
||||
hue-3: #a626a4
|
||||
hue-4: #50a14f
|
||||
hue-5: #e45649
|
||||
hue-5-2: #c91243
|
||||
hue-6: #986801
|
||||
hue-6-2: #c18401
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
color: #383a42;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #a0a1a7;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #a626a4;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e45649;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #0184bb;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta .hljs-string {
|
||||
color: #50a14f;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #986801;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #4078f2;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-title.class_,
|
||||
.hljs-class .hljs-title {
|
||||
color: #c18401;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@@ -19,6 +19,8 @@
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -26,7 +28,8 @@
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css">
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
@@ -39,7 +42,11 @@
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<a href="/blog" style="color:#000;">Blog index</a>
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
@@ -63,7 +70,7 @@
|
||||
<p><strong>Warning</strong>: I want to state clearly that I’m not a mathematician, I’m just an amateur on math studying in my free time, and this article is just an attempt to try to sort the notes that I took while reading about the KZG Commitments.</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Last week I posted some <em><a href="https://arnaucube.com/blog/kzg-commitments.html">notes on KZG Commitmens</a></em>, which overviews the scheme for single proofs. The current notes, try to overview the <em>batch proof</em> iteraton on KZG Commitments, and the <em>vector commitment</em> usage of it. Again (as in the previous post), big thanks to <a href="https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html">Dankrad Feist</a> and <a href="https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html">Alin Tomescu</a> for their articles which helped me to follow a bit the reasoing behind this, and again, I recommend spending the time reading their articles instead of this current notes.</p>
|
||||
<p>Last week I posted some <em><a href="https://arnaucube.com/blog/kzg-commitments.html">notes on KZG Commitmens</a></em>, which overviews the scheme for single proofs. The current notes, try to overview the <em>batch proof</em> iteraton on KZG Commitments, and the <em>vector commitment</em> usage of it. Again (as in the previous post), big thanks to <a href="https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html">Dankrad Feist</a> and <a href="https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html">Alin Tomescu</a> for their articles which helped me to follow a bit the reasoing behind this, and again, I recommend spending the time <strong>reading their articles (<a href="https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html">1</a>, <a href="https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html">2</a>) instead of this current notes</strong>.</p>
|
||||
|
||||
<h4>Batch proof</h4>
|
||||
|
||||
@@ -72,10 +79,10 @@ Let <span class="math inline">\((z_0, y_0), (z_1, y_1), ..., (z_k, y_k)\)</span>
|
||||
The <em>commitment</em> to the polynomial stands the same than for single proofs: <span class="math inline">\(c=[p(\tau)]_1\)</span>.</p>
|
||||
|
||||
<p>For the evaluation proof, while in the single proofs we compute <span class="math inline">\(q(x) = \frac{p(x)-y}{x-z}\)</span>, we will replace <span class="math inline">\(y\)</span> and <span class="math inline">\(x-z\)</span> by the following two polynomials.
|
||||
The constant <span class="math inline">\(y\)</span> is replaced by a polynomial that has roots at all the points that we want to prove. This is achieved by computing the <a href="/blog/shamir-secret-sharing.html#lagrange-polynomial%20interpolation">Lagrange interpolation</a> for the given set of points:</p>
|
||||
The constant <span class="math inline">\(y\)</span> is replaced by a polynomial that has roots at all the points that we want to prove. This is achieved by computing the <a href="shamir-secret-sharing.html#lagrange-polynomial%20interpolation">Lagrange interpolation</a> for the given set of points:</p>
|
||||
<p><span class="math display">\[
|
||||
I(x) = \sum_{j=0}^k y_j l_j(x)\newline
|
||||
where \space\space\space l_j(x) = \prod\_{0\leq m \leq k} \frac{x-x_m}{x_j - x_m}
|
||||
where \space\space\space l_j(x) = \prod_{0\leq m \leq k} \frac{x-x_m}{x_j - x_m}
|
||||
\]</span></p><p>And the <span class="math inline">\(x-z\)</span>, which was to ensure that <span class="math inline">\(q(x)\)</span> had a root at <span class="math inline">\(z\)</span>, now, as we want to ensure that <span class="math inline">\(q(x)\)</span> has roots at all the points of the commitment, we will use the <em>zero polynomial</em>:</p>
|
||||
<p><span class="math display">\[
|
||||
Z(x) = \prod_{i=0}^{k} x-z_i =\newline
|
||||
@@ -107,12 +114,15 @@ The problem with Merkle Trees is that the proof size grows linearly with the siz
|
||||
|
||||
<p>I’m fascinated by this scheme and its potential. One next rabbit hole (related to KZG Commitments) to look at, would be the <a href="https://vitalik.ca/general/2019/09/22/plonk.html">Plonk</a> and other similar constructions. Also, another use case that is getting attention in the Ethereum community is the <a href="https://vitalik.ca/general/2021/06/18/verkle.html"><em>Verkle Trees</em></a>.</p>
|
||||
|
||||
<p>As in the previous notes, in order to try to put in practice the concepts, I’ve added the <em>batch proof</em> logic at <a href="https://github.com/arnaucube/kzg-commitments-study">https://github.com/arnaucube/kzg-commitments-study</a>.</p>
|
||||
<p>As in the previous notes, in order to try to put in practice the concepts, I’ve added the implementation of the <em>batch proof</em> logic at the Go KZG implementation <a href="https://github.com/arnaucube/kzg-commitments-study">https://github.com/arnaucube/kzg-commitments-study</a>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
@@ -182,7 +192,7 @@ The problem with Merkle Trees is that the proof size grows linearly with the siz
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -26,7 +28,8 @@
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css">
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
@@ -39,7 +42,11 @@
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<a href="/blog" style="color:#000;">Blog index</a>
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
@@ -63,7 +70,7 @@
|
||||
<p><strong>Warning</strong>: I want to state clearly that I’m not a mathematician, I’m just an amateur on math studying in my free time, and this article is just an attempt to try to sort the notes that I took while reading about the KZG Commitments.</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Few weeks ago I started reading about <a href="https://www.iacr.org/archive/asiacrypt2010/6477178/6477178.pdf">KZG Commitments</a> from the articles written by <a href="https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html">Dankrad Feist</a>, by <a href="https://hackmd.io/@tompocock/Hk2A7BD6U">Tom Walton-Pocock</a> and by <a href="https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html">Alin Tomescu</a>. I want to thank them, because their articles helped me to understand a bit the concepts. I recommend spending the time reading their articles instead of this current notes.</p>
|
||||
<p>Few weeks ago I started reading about <a href="https://www.iacr.org/archive/asiacrypt2010/6477178/6477178.pdf">KZG Commitments</a> from the articles written by <a href="https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html">Dankrad Feist</a>, by <a href="https://hackmd.io/@tompocock/Hk2A7BD6U">Tom Walton-Pocock</a> and by <a href="https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html">Alin Tomescu</a>. I want to thank them, because their articles helped me to understand a bit the concepts. I recommend spending the time reading their articles (<a href="https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html">1</a>, <a href="https://hackmd.io/@tompocock/Hk2A7BD6U">2</a>, <a href="https://alinush.github.io/2020/05/06/kzg-polynomial-commitments.html">3</a>) instead of this current notes.</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
@@ -129,7 +136,7 @@ $<span class="math inline">\(\hat{e}(\pi, [\tau]_2 - [z]_2) == \hat{e}(c - [y]_1
|
||||
|
||||
<h3>Conclusions</h3>
|
||||
|
||||
<p>The content covered in this notes is just a quick overview, but allows us to see the potential of the scheme. One next iteration from what we’ve seen is the approach to do batch proofs, which allows us to evaluate at multiple points with a single evaluation proof. This scheme can be used as a <em>vector commitment</em>, using a polynomial where the <span class="math inline">\(p(i) = x_i\)</span> for all values of <span class="math inline">\(x_i\)</span> of the vector, which can be obtained from the <span class="math inline">\(x_i\)</span> values and computing the <a href="https://en.wikipedia.org/wiki/Lagrange_polynomial">Lagrange interpolation</a>. This is quite useful combined with the mentioned batch proofs. The <em>batch proofs</em> logic can be found at the <a href="https://arnaucube.com/blog/kzg-batch-proof.html">blog/kzg-batch-proof</a> notes (kind of the continuation of the current notes).</p>
|
||||
<p>The content covered in this notes is just a quick overview, but allows us to see the potential of the scheme. One next iteration from what we’ve seen is the approach to do batch proofs, which allows us to evaluate at multiple points with a single evaluation proof. This scheme can be used as a <em>vector commitment</em>, using a polynomial where the <span class="math inline">\(p(i) = x_i\)</span> for all values of <span class="math inline">\(x_i\)</span> of the vector, which can be obtained from the <span class="math inline">\(x_i\)</span> values and computing the <a href="shamir-secret-sharing.html#lagrange-polynomial%20interpolation">Lagrange interpolation</a>. This is quite useful combined with the mentioned batch proofs. The <em>batch proofs</em> logic can be found at the <a href="https://arnaucube.com/blog/kzg-batch-proof.html">blog/kzg-batch-proof</a> notes (kind of the continuation of the current notes).</p>
|
||||
|
||||
<p>As a final note, in order to try to digest the notes, I’ve did a <em>toy implementation</em> of this scheme at <a href="https://github.com/arnaucube/kzg-commitments-study">https://github.com/arnaucube/kzg-commitments-study</a>. It’s quite simple, but contains the logic overviewed in this notes.</p>
|
||||
|
||||
@@ -140,6 +147,9 @@ $<span class="math inline">\(\hat{e}(\pi, [\tau]_2 - [z]_2) == \hat{e}(c - [y]_1
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
@@ -209,7 +219,7 @@ $<span class="math inline">\(\hat{e}(\pi, [\tau]_2 - [z]_2) == \hat{e}(c - [y]_1
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
|
||||
134
public/notes.html
Normal file
@@ -0,0 +1,134 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta name="description" content="[blogo-summary]" />
|
||||
<meta charset="utf-8">
|
||||
<title>Notes</title>
|
||||
<meta name="title" content="Notes">
|
||||
<meta name="description" content="Notes">
|
||||
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- o_gradient_background" -->
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
<input onclick="switchTheme()" type="checkbox" name="onoffswitch" class="onoffswitch-checkbox"
|
||||
id="themeSwitcher">
|
||||
<label class="onoffswitch-label" for="themeSwitcher"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img style="height:5px; width:100%; margin-top:8px;" src="img/gradient-line.jpg" />
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
<!-- in markdown which later is converted to html -->
|
||||
<div id="markdown" class="container" style="margin-top:40px;max-width:800px;">
|
||||
### Notes:
|
||||
Usually while reading papers I take handwritten notes, this section contains some of them re-written to LaTeX.
|
||||
The notes are not complete, don’t include all the steps neither the explanations neither most of the proofs.
|
||||
I use these notes to revisit the concepts after some time of reading the paper.
|
||||
- [Notes on Halo](https://raw.githubusercontent.com/arnaucube/math/master/notes_halo.pdf)
|
||||
- [Notes on Sigma protocol and OR proofs](https://raw.githubusercontent.com/arnaucube/math/master/sigma-or-notes.pdf)
|
||||
- [Notes on BLS signatures](https://raw.githubusercontent.com/arnaucube/math/master/notes_bls-sig.pdf)
|
||||
- [Notes on Sonic](https://raw.githubusercontent.com/arnaucube/math/master/notes_sonic.pdf)
|
||||
- [Notes on Weil Pairing](https://raw.githubusercontent.com/arnaucube/math/master/pairings.pdf)
|
||||
</div>
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Back to the blog</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
style="color:gray;text-decoration:none;"
|
||||
target="_blank">twitter.com/arnaucube</a>
|
||||
</li>
|
||||
<li><a href="https://github.com/arnaucube"
|
||||
style="color:gray;text-decoration:none;"
|
||||
target="_blank">github.com/arnaucube</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
renderMathInElement(document.body, {
|
||||
displayMode: false,
|
||||
// customised options
|
||||
// • auto-render specific keys, e.g.:
|
||||
delimiters: [
|
||||
{left: '$$', right: '$$', display: true},
|
||||
{left: '$', right: '$', display: false},
|
||||
{left: "\\[", right: "\\]", display: true},
|
||||
{left: "\\(", right: "\\)", display: false},
|
||||
],
|
||||
// • rendering keys, e.g.:
|
||||
throwOnError : true
|
||||
});
|
||||
});
|
||||
|
||||
///
|
||||
let theme = localStorage.getItem("theme");
|
||||
if ((theme === "light-theme")||(theme==null)) {
|
||||
theme = "light-theme";
|
||||
document.getElementById("themeSwitcher").checked = false;
|
||||
} else if (theme === "dark-theme") {
|
||||
theme = "dark-theme";
|
||||
document.getElementById("themeSwitcher").checked = true;
|
||||
}
|
||||
document.body.className = theme;
|
||||
localStorage.setItem("theme", theme);
|
||||
|
||||
function switchTheme() {
|
||||
theme = localStorage.getItem("theme");
|
||||
if (theme === "light-theme") {
|
||||
theme = "dark-theme";
|
||||
document.getElementById("themeSwitcher").checked = true;
|
||||
} else {
|
||||
theme = "light-theme";
|
||||
document.getElementById("themeSwitcher").checked = false;
|
||||
}
|
||||
document.body.className = theme;
|
||||
localStorage.setItem("theme", theme);
|
||||
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="js/drawdown.js"></script>
|
||||
|
||||
<script>
|
||||
let content = document.getElementById("markdown").innerHTML;
|
||||
let md = markdown(content);
|
||||
document.getElementById("markdown").innerHTML = md;
|
||||
</script>
|
||||
|
||||
<script src="js/external-links.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
416
public/powersoftau.html
Normal file
@@ -0,0 +1,416 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta name="description" content="In the following notes we go over the ideas behind the Powers of Tau ceremony, how participants contribute and how the contributions are verified (logic & code). We focus on the Ethereum's upcoming KZG-Ceremony." />
|
||||
<meta charset="utf-8">
|
||||
<title> Implementing the powers of tau contributor - arnaucube - blog</title>
|
||||
<meta name="title" content=" Implementing the powers of tau contributor - arnaucube - blog">
|
||||
<meta name="description" content="In the following notes we go over the ideas behind the Powers of Tau ceremony, how participants contribute and how the contributions are verified (logic & code). We focus on the Ethereum's upcoming KZG-Ceremony.">
|
||||
|
||||
<meta property="og:title" content=" Implementing the powers of tau contributor - arnaucube - blog" />
|
||||
<meta property="og:description" content="In the following notes we go over the ideas behind the Powers of Tau ceremony, how participants contribute and how the contributions are verified (logic & code). We focus on the Ethereum's upcoming KZG-Ceremony." />
|
||||
<meta property="og:url" content="https://arnaucube.com/blog/powersoftau.html" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:image" content="https://arnaucube.com/blog/" />
|
||||
<meta name="twitter:title" content=" Implementing the powers of tau contributor - arnaucube - blog">
|
||||
<meta name="twitter:description" content="In the following notes we go over the ideas behind the Powers of Tau ceremony, how participants contribute and how the contributions are verified (logic & code). We focus on the Ethereum's upcoming KZG-Ceremony.">
|
||||
<meta name="twitter:image" content="https://arnaucube.com/blog/">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
<link rel="stylesheet" href="js/katex/katex.min.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- o_gradient_background" -->
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
<input onclick="switchTheme()" type="checkbox" name="onoffswitch" class="onoffswitch-checkbox"
|
||||
id="themeSwitcher">
|
||||
<label class="onoffswitch-label" for="themeSwitcher"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img style="height:5px; width:100%; margin-top:8px;" src="img/gradient-line.jpg" />
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
<div class="container" style="margin-top:40px;max-width:800px;">
|
||||
<h1>Implementing the powers of tau contributor</h1>
|
||||
|
||||
<p><em>2023-01-02</em></p>
|
||||
|
||||
<p>In the following notes we go over the ideas behind the <em>Powers of Tau</em> ceremony, how participants contribute and how the contributions are verified.</p>
|
||||
|
||||
<p>The powers of tau are used in schemes such as KZG Commitments, and by consequence in the Plonk-KZG and in Verkle Trees use cases, which the later ones are in the Ethereum roadmap, but probably the ceremony output will be used in many other applications.
|
||||
The ceremony is named also as <em>Trusted Setup Ceremony</em>, and <em>SRS</em> (Structured Reference String) in Plonk and Sonic papers.</p>
|
||||
|
||||
<p>Specifically these notes focus on the powers of tau ceremony that is <a href="https://github.com/ethereum/kzg-ceremony">being prepared in Ethereum</a>. For learning about the specifics of the powers of tau reasoning, I’ve used the following two documents:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/ethereum/kzg-ceremony/blob/main/KZG10-Ceremony-audit-report.pdf">KZG10-Ceremony-audit-report.pdf, by SECBIT Labs</a></li>
|
||||
<li><a href="https://arxiv.org/abs/1906.07221v1"><em>Why and how zkSNARKs work</em>, by Maksym Petkus</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Additionally, <a href="https://vitalik.ca/general/2022/03/14/trustedsetup.html">this article by Vitalik Buterin</a> explains the ideas behind trusted setups.</p>
|
||||
|
||||
<p>The contents of these notes are distributed as follows:
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#the-main idea">The main idea</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#preliminaries">Preliminaries</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#participant-contribution">Participant contribution</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#proof-of correct computation">Proof of correct computation</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#contribution-verification">Contribution verification</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#full-flow">Full flow</a>
|
||||
<br><span style="margin-right:40px;"></span>
|
||||
<a style="color:gray;" href="#conclusions">Conclusions</a></p>
|
||||
|
||||
<p>Across these notes some snippets of Sage code are provided, the full Sage code can be found <a href="https://github.com/arnaucube/math/blob/master/powersoftau.sage">here</a>, and also a <a href="https://github.com/arnaucube/eth-kzg-ceremony-alt">full implementation in Go</a> which also contains a CLI to participate in the upcomming Ethereum KZG-Ceremony.</p>
|
||||
|
||||
<h3>The main idea</h3>
|
||||
|
||||
<p>The main idea is that we want to compute <span class="math inline">\(\tau^0, \tau^1, \tau^2, \ldots, \tau^{n-1}\)</span>, where <span class="math inline">\(\tau\)</span> should be unknown. In order to achieve this, we use some technics to combine different <span class="math inline">\(\tau\)</span>s from different contributors, in a way where we obtain the powers of a tau which is a combination of the different secret taus (<span class="math inline">\(\tau_{p_i}\)</span>) of the different participants.</p>
|
||||
|
||||
<p>The <span class="math inline">\(\tau_{p_i}\)</span> should be secret for each participant, furthermore, it should be generated from some source of randomness and destroyed at the end.</p>
|
||||
|
||||
<p>As we’ve mentioned, we want to come up with the powers of tau where tau is a combination of the taus from all the participants, in a way where as long as there is at least one honest participant, which does not share their part of the final tau, the combined-tau can not be recovered and the ceremony is assumed to be safe.</p>
|
||||
|
||||
<p>This is important, because if somebody has knowledge of the tau value, could generate fake proofs. As an example <a href="https://medium.com/qed-it/how-toxic-is-the-waste-in-a-zksnark-trusted-setup-9b250d59bdb4">this article by Kobi Gurkan</a> shows how fake BCTV14a proofs can be generated if tau is known.</p>
|
||||
|
||||
<p>This is relevant in the context of <a href="https://arnaucube.com/blog/kzg-commitments.html">KZG Commitments</a>, specially in the roadmap of Ethereum.
|
||||
Ethereum will run the Ceremony which will be used at least in <a href="https://eips.ethereum.org/EIPS/eip-4844">EIP-4844</a>. That’s why EF’s is encouraging people to participate in various ways, as the Ceremony is considered safe as long as there is at least one honest participant, with the idea that if you participate, assuming that you consider yourself honest, you can consider the Ceremony safe.</p>
|
||||
|
||||
<p>The output of the ceremony will be used in the Ethereum VerkleTrees, which uses KZG Commitments, but also it will be useful for Plonk-KZG proofs.</p>
|
||||
|
||||
<p>So the best way to trust the output of the ceremony is by becoming a participant yourself!, Furhermore, by participating with your own code ^^</p>
|
||||
|
||||
<h3>Preliminaries</h3>
|
||||
|
||||
<p><strong>Pairing</strong><br>
|
||||
We will try to focus only in the concepts that we strictly need for the implementation, so we will treat Pairings as a black box with some simplified properties.</p>
|
||||
|
||||
<p>For our use case, we use asymmetric bilinear pairings. We can see an asymmetric bilinear pairing as a function that maps an element from the group <span class="math inline">\(\mathbb{G_1}\)</span> and another one from <span class="math inline">\(\mathbb{G_2}\)</span> into an el element of the group <span class="math inline">\(\mathbb{G_T}\)</span>.</p>
|
||||
<p><span class="math display">\[e: \mathbb{G_1} \times \mathbb{G_2} \longrightarrow \mathbb{G_T}\]</span></p><p>For our use case, we’ll focus only on one property, <em>bilinearity</em>.</p>
|
||||
|
||||
<p>Let <span class="math inline">\(a, b \in \mathbb{F_q}\)</span>, <span class="math inline">\(\mathbb{G}_1 = \langle G \rangle\)</span> and <span class="math inline">\(\mathbb{G}_2 = \langle H \rangle~\)</span> (In other words, <span class="math inline">\(G\)</span> is the generator of <span class="math inline">\(\mathbb{G}_1\)</span>, and <span class="math inline">\(H\)</span> is the generator of <span class="math inline">\(\mathbb{G}_2\)</span>).</p>
|
||||
|
||||
<p>Then, the bilinearity property tells us that</p>
|
||||
<p><span class="math display">\[e(a \cdot G,~b \cdot H) = e((a \cdot b) \cdot G,~H) = e(G,~(a \cdot b) \cdot H)\]</span></p><p>For better readability, we will use the following notation to represent the scalar point multiplication:</p>
|
||||
<p><span class="math display">\[[x]_1 = x \cdot G \in \mathbb{G}_1\newline
|
||||
[x]_2 = x \cdot H \in \mathbb{G}_2\]</span></p><p>So, our previous bilinearity example would look like</p>
|
||||
<p><span class="math display">\[e([a]_1, [b]_2) = e([a \cdot b]_1, [1]_2) = e([1]_1, [a \cdot b]_2)\]</span></p><p>In our practical use case, we use the <a href="https://hackmd.io/@benjaminion/bls12-381">BLS12-381</a> pairing, where <span class="math inline">\(\mathbb{G}_1, \mathbb{G}_2\)</span> are elliptic curve groups, thus the points <span class="math inline">\(G, H\)</span> are elliptic curve points.</p>
|
||||
|
||||
<p><strong>Code</strong><br>
|
||||
For the code examples we’ll use <a href="https://www.sagemath.org">SageMath</a>, but the code would look quite similar in Python, and the same logic can be implemented in any language.</p>
|
||||
|
||||
<h3>Participant contribution</h3>
|
||||
|
||||
<p>In the context of SRS (Structured Reference String), the powers of tau consist of an array containing the scalar multiplication of the generator point by each power of tau, eg. <span class="math inline">\(\tau^0 \cdot G,~\tau^1 \cdot G,~\tau^2 \cdot G,~\tau^3 \cdot G \ldots\)</span></p>
|
||||
|
||||
<p>For our case, we’ll generate <span class="math inline">\(n\)</span> powers of tau on <span class="math inline">\(\mathbb{G}_1\)</span>, and <span class="math inline">\(m\)</span> on <span class="math inline">\(\mathbb{G}_2\)</span>. We will denote the combination of both <span class="math inline">\(\mathbb{G}_1\)</span> and <span class="math inline">\(\mathbb{G}_2\)</span> powers of tau by SRS.</p>
|
||||
|
||||
<p>Each participant will obtain the previous-participant generated SRS, which is formed by</p>
|
||||
<p><span class="math display">\[\{ [\tau^0]_1, [\tau^1]_1, [\tau^2]_2, \ldots, [\tau^{n-1}]_1 \},\\
|
||||
\{ [\tau^0]_2, [\tau^1]_2, [\tau^2]_2, \ldots, [\tau^{m-1}]_2 \}\]</span></p><p>for simplicity, we will represent it as</p>
|
||||
<p><span class="math display">\[\{~[~\tau^i]_1~\}^{n-1}_{i=0},~\{~[~\tau^i]_2~\}^{m-1}_{j=0}\]</span></p><p>Each participant generates their secret random tau <span class="math inline">\(\tau_p\)</span>, which to avoid confusion we will denote as <span class="math inline">\(p \in \mathbb{F}_r\)</span>. From it, the participant can compute <span class="math inline">\([p]_2 \in \mathbb{G}_2\)</span>.</p>
|
||||
|
||||
<p>Then the participant proceeds to update the reference string (SRS), by multiplying each element by <span class="math inline">\(p^i\)</span>:</p>
|
||||
<p><span class="math display">\[\{~ p^i \cdot [~ \tau^i]_1~\}^{n-1}_{i=0},~\{~ p^i \cdot [~\tau^i]_2~\}^{m-1}_{j=0}\]</span></p><p>which, by the properties of scalar multiplication of a point, is equivalent to</p>
|
||||
<p><span class="math display">\[\{~ [~ (p \cdot \tau)^i]_1~\}^{n-1}_{i=0},~\{~ [~ (p \cdot \tau)^i]_2~\}^{m-1}_{j=0}\]</span></p><p>and we denote <span class="math inline">\(p \cdot \tau\)</span> as <span class="math inline">\(\tau'\)</span>, so we can write the previous expression as</p>
|
||||
<p><span class="math display">\[\{~[~\tau'^i]_1~\}^{n-1}_{i=0},~\{~[~\tau'^i]_2~\}^{m-1}_{j=0}\]</span></p><p>which is</p>
|
||||
<p><span class="math display">\[\{ [(\tau \cdot p)^0]_1, [(\tau \cdot p)^1]_1, [(\tau \cdot p)^2]_2, \ldots, [(\tau \cdot p)^{n-1}]_1 \},\\
|
||||
\{ [(\tau \cdot p)^0]_2, [(\tau \cdot p)^1]_2, [(\tau \cdot p)^2]_2, \ldots, [(\tau \cdot p)^{m-1}]_2 \}\]</span></p><p>Notice that the contributor does not know the previous <span class="math inline">\(\tau\)</span>, but can obtain <span class="math inline">\((\tau \cdot p)^i\)</span>.</p>
|
||||
|
||||
<p><br><br>
|
||||
We can express the previous logic as follows:</p>
|
||||
|
||||
<pre><code class="language-python">def compute_contribution(new_tau, prev_srs):
|
||||
g1s = [None] * len(prev_srs[0])
|
||||
g2s = [None] * len(prev_srs[1])
|
||||
srs = [g1s, g2s]
|
||||
Q = e.r
|
||||
|
||||
# compute [τ'⁰]₁, [τ'¹]₁, [τ'²]₁, ..., [τ'ⁿ⁻¹]₁, where n = len(prev_srs.G1s)
|
||||
for i in range(0, len(prev_srs[0])):
|
||||
srs[0][i] = (new_tau^i) * prev_srs[0][i]
|
||||
|
||||
# compute [τ'⁰]₂, [τ'¹]₂, [τ'²]₂, ..., [τ'ⁿ⁻¹]₂, where n = len(prev_srs.G2s)
|
||||
for i in range(0, len(prev_srs[1])):
|
||||
srs[1][i] = (new_tau^i) * prev_srs[1][i]
|
||||
|
||||
return srs
|
||||
</code></pre>
|
||||
|
||||
<h3>Proof of correct computation</h3>
|
||||
|
||||
<p>The participant will compute the proof, which consists of</p>
|
||||
<p><span class="math display">\[\pi = ([\tau']_1,~[p]_2)\]</span></p><p>which is equivalent to <span class="math inline">\(\pi = (\tau' \cdot G,~p \cdot H) = ((p \cdot \tau) \cdot G,~p \cdot H)\)</span></p>
|
||||
|
||||
<p>In the next section we will see how this is used to verify the contribution correct computation.</p>
|
||||
|
||||
<p><br>
|
||||
We implement this logic as follows:</p>
|
||||
|
||||
<pre><code class="language-python">def generate_proof(tau, prev_srs, new_srs):
|
||||
# g_1^{tau'} = g_1^{p * tau} = SRS_G1s[1] * p
|
||||
g1_ptau = prev_srs[0][1] * tau
|
||||
# g_2^{p}
|
||||
g2_p = tau * e.G2
|
||||
return [g1_ptau, g2_p]
|
||||
</code></pre>
|
||||
|
||||
<h3>Contribution verification</h3>
|
||||
|
||||
<p>This is the interesting part. We want to check that the new SRS is well computed from the previous SRS together with the new tau. We want to avoid accepting contributions that do not follow the powers of tau structure, or that contain empty elements or that do not derive from the previous SRS.</p>
|
||||
|
||||
<p>Following the powers of tau structure means that</p>
|
||||
<p><span class="math display">\[\tau'^{i+1} = \tau' \cdot \tau'^i ~~\forall~i \in [1, n-1]\]</span></p><p>And the relation between the new SRS and the previous SRS is</p>
|
||||
<p><span class="math display">\[\tau' = \tau \cdot p\]</span></p><p>where <span class="math inline">\(\tau\)</span> is the secret element from the previous SRS and <span class="math inline">\(p\)</span> is the secret one from the new SRS, resulting in the combined <span class="math inline">\(\tau'\)</span>.</p>
|
||||
|
||||
<p>Now, we’re interested into how we can check these relations in the context of the SRS elements. A new contribution can be verified as follows:</p>
|
||||
|
||||
<ol>
|
||||
<li><p>Check that elements of the new SRS are non-empty, non-zero and in the correct prime order subgroups.</p></li>
|
||||
|
||||
<li><p>Get the proof (<span class="math inline">\(\pi = ([\tau']_1, [p]_2)\)</span>), and confirm that the 1st element is equal to the element in position 1 <span class="math inline">\([\tau'^1]_1\)</span> of the new SRS (which corresponds to <span class="math inline">\(\tau'\)</span> powered to <span class="math inline">\(1\)</span>).</p></li>
|
||||
|
||||
<li><p>Check that <span class="math inline">\(\tau'\)</span> (the new SRS) is correctly related to <span class="math inline">\(\tau\)</span> (the previous SRS).</p>
|
||||
|
||||
<p>To check this, we rely on the pairing properties and we use the proof value generated by the contributor, which consists of <span class="math inline">\([p]_2\)</span></p>
|
||||
<p><span class="math display">\[e([\tau]_1, [p]_2) \stackrel{?}{=} e([\tau']_1, [1]_2)\]</span></p><p>We can see how this holds, as <span class="math inline">\(\tau' = p \cdot \tau\)</span>, and by the bilinear property of the pairing (see <a href="#preliminaries">Preliminearies section</a>) we have <span class="math inline">\(e(a \cdot G, b \cdot H) = e((a \cdot b) \cdot G, H)\)</span>, which in our notation is represented as</p>
|
||||
<p><span class="math display">\[e([a]_1, [b]_2) = e([a \cdot b]_1, [1]_2)\]</span></p><p>by applying this to our case we can see that:</p>
|
||||
<p><span class="math display">\[e([\tau]_1, [p]_2) = e([\tau \cdot p]_1, [1]_2) = e([\tau']_1, [1]_2)\]</span></p></li>
|
||||
|
||||
<li><p>Check if the new SRS follows the powers of tau structure:</p>
|
||||
<p><span class="math display">\[e([\tau'^i]_1, [\tau']_2) \stackrel{?}{=} e([\tau'^{i+1}]_1, [1]_2) ~~ \forall ~i \in [1, n-1]\]</span></p><p><span class="math display">\[e([\tau']_1, [\tau'^j]_2) \stackrel{?}{=} e([1]_1, [\tau'^{j+1}]_2) ~~ \forall ~i \in [1, m-1]\]</span></p><p>Which, again, by the bilinarity property, we can see that</p>
|
||||
<p><span class="math display">\[e([\tau'^i]_1, [\tau']_2) = e([\tau'^{i+1}]_1, [1]_2)\]</span></p><p>is enforcing that <span class="math inline">\(\tau'^i \cdot \tau'^1 = \tau'^{i+1}\)</span>.</p>
|
||||
|
||||
<p>And the same for</p>
|
||||
<p><span class="math display">\[e([\tau']_1, [\tau'^j]_2) = e([1]_1, [\tau'^{j+1}]_2)\]</span></p><p>which checks that <span class="math inline">\(\tau'^1 \cdot \tau'^j = \tau'^{j+1}\)</span>.</p>
|
||||
|
||||
<p>With this check, we’re ensuring that each power of tau of the SRS is consistent with the previous one.</p></li>
|
||||
</ol>
|
||||
|
||||
<p><br><br>
|
||||
The complete verification function would look like</p>
|
||||
|
||||
<pre><code class="language-python">def verify(prev_srs, new_srs, proof):
|
||||
# 1. check that elements of the newSRS are valid points
|
||||
for i in range(0, len(new_srs[0])-1):
|
||||
assert new_srs[0][i] != None
|
||||
assert new_srs[0][i] != e.E1(0)
|
||||
assert new_srs[0][i] in e.E1
|
||||
for i in range(0, len(new_srs[1])-1):
|
||||
assert new_srs[1][i] != None
|
||||
assert new_srs[1][i] != e.E1(0)
|
||||
assert new_srs[1][i] in e.E2
|
||||
|
||||
# 2. check proof.G1PTau == newSRS.G1Powers[1]
|
||||
assert proof[0] == new_srs[0][1]
|
||||
|
||||
# 3. check newSRS.G1s[1] (g₁^τ'), is correctly related to prev_srs.G1s[1] (g₁^τ)
|
||||
# e([τ]₁, [p]₂) == e([τ']₁, [1]₂)
|
||||
assert e.pair(prev_srs[0][1], proof[1]) == e.pair(new_srs[0][1], e.G2)
|
||||
|
||||
# 4. check newSRS following the powers of tau structure
|
||||
# i) e([τ'ⁱ]₁, [τ']₂) == e([τ'ⁱ⁺¹]₁, [1]₂), for i ∈ [1, n−1]
|
||||
for i in range(0, len(new_srs[0])-1):
|
||||
assert e.pair(new_srs[0][i], new_srs[1][1]) == e.pair(new_srs[0][i+1], e.G2)
|
||||
|
||||
# ii) e([τ']₁, [τ'ʲ]₂) == e([1]₁, [τ'ʲ⁺¹]₂), for j ∈ [1, m−1]
|
||||
for i in range(0, len(new_srs[1])-1):
|
||||
assert e.pair(new_srs[0][1], new_srs[1][i]) == e.pair(e.G1, new_srs[1][i+1])
|
||||
</code></pre>
|
||||
|
||||
<h3>Full flow</h3>
|
||||
|
||||
<p>Now that we have the three methods (<em>compute_contribution, generate_proof, verify</em>), it’s a matter of using them.</p>
|
||||
|
||||
<p>First let’s add a couple of helpers to our code:</p>
|
||||
|
||||
<pre><code class="language-python"># here we import the BLS12-381 pairing machinery
|
||||
load("bls12-381.sage") # file from https://github.com/arnaucube/math/blob/master/bls12-381.sage
|
||||
e = Pairing()
|
||||
|
||||
# this method generates a SRS filled by the generator points of G1 & G2
|
||||
def new_empty_SRS(nG1, nG2):
|
||||
g1s = [None] * nG1
|
||||
g2s = [None] * nG2
|
||||
for i in range(0, nG1):
|
||||
g1s[i] = e.G1
|
||||
for i in range(0, nG2):
|
||||
g2s[i] = e.G2
|
||||
|
||||
return [g1s, g2s]
|
||||
</code></pre>
|
||||
|
||||
<p>Let’s do the flow:</p>
|
||||
|
||||
<pre><code class="language-python"># generate a fake previous-SRS
|
||||
(prev_srs) = new_empty_SRS(5, 3)
|
||||
|
||||
# set a random value to be used for our tau
|
||||
random = 12345 # this would be a random value
|
||||
tau = e.F1(random)
|
||||
|
||||
# compute our contribution, from the previous SRS and our tau
|
||||
new_srs = compute_contribution(tau, prev_srs)
|
||||
|
||||
# generate a proof of correct computation of our contribution
|
||||
proof = generate_proof(tau, prev_srs, new_srs)
|
||||
|
||||
# verify the proof for the given prev_srs and the new_srs
|
||||
verify(prev_srs, new_srs, proof)
|
||||
</code></pre>
|
||||
|
||||
<h2>Conclusions</h2>
|
||||
|
||||
<p>As we’ve seen, we can prove and verify the correct computation of the new SRS with few operations.</p>
|
||||
|
||||
<p>From here the next thing would be to implement the <a href="https://github.com/ethereum/kzg-ceremony-specs/blob/master/apiSpec/sequencerApi.yml">interaction with the Sequencer</a>, in order to authenticate the participant, fetch the previous SRS, and send the new SRS and proof.</p>
|
||||
|
||||
<p>You can find the Sage example that we’ve been using <a href="https://github.com/arnaucube/math/blob/master/powersoftau.sage">here</a>, and a full Go implementation here: <a href="https://github.com/arnaucube/eth-kzg-ceremony-alt">https://github.com/arnaucube/eth-kzg-ceremony-alt</a> (which uses <a href="https://github.com/kilic/bls12-381">Kilic’s BLS12-381 implementation</a>, and includes also the interaction with the Sequencer and a CLI).
|
||||
There is also the EF’s rust implementation <a href="https://github.com/crate-crypto/small-powers-of-tau">small-powers-of-tau</a> which has been audited. The same logic can be implemented in the language of your choice.
|
||||
<br><br></p>
|
||||
|
||||
<p><a href="https://github.com/arnaucube/eth-kzg-ceremony-alt" target="_blank" title="https://github.com/arnaucube/eth-kzg-ceremony-alt">
|
||||
<img src="img/posts/powersoftau/kzg-ceremony-screenshot.png" style="width:100%;" />
|
||||
<span style="font-size:80%; color:gray;font-style:italic;">Screenshot of the eth-kzg-ceremony-alt CLI after contributing to the testnet ceremony.</a>
|
||||
</a></p>
|
||||
|
||||
<p>Another interesting piece is the <em>randomness generation</em>. In our example, for simplicity, tau was hardcoded in the code, but in the real world case we would use some source of randomness to generate our secret value. Here you can get <a href="https://www.youtube.com/watch?v=I4cDAqeEmpU">as creative as you can</a>, and probably we will see some cool approaches for the Ethereum-KZG-Ceremony.</p>
|
||||
|
||||
<p>This ceremony output is quite important, as it will be used in many applications once available. It will be used in the Ethereum protocol for the KZG Commitments on EIP-4844, but also on many other applications (some of them unrelated to Ethereum!). For example, any (up to the degree upperbound) Plonk-KZG deployment could reuse this ceremony to avoid needing to compute their own.
|
||||
So it’s important to gather a notable amount of participants in the ceremony, and probably participate to it by yourself! (as if you’re contributing you know that at least there has been one honest contribution (you)).</p>
|
||||
|
||||
<p>You can find more info on the Ethereum’s KZG Ceremony here: <a href="https://ceremony.ethereum.org">https://ceremony.ethereum.org</a> (which includes also a nice contributor webapp to participate from the browser).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
style="color:gray;text-decoration:none;"
|
||||
target="_blank">twitter.com/arnaucube</a>
|
||||
</li>
|
||||
<li><a href="https://github.com/arnaucube"
|
||||
style="color:gray;text-decoration:none;"
|
||||
target="_blank">github.com/arnaucube</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="row" style="display:inline-block;">
|
||||
Blog made with <a href="http://github.com/arnaucube/blogo/"
|
||||
target="_blank" style="color: gray;text-decoration:none;">Blogo</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
<script src="js/external-links.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
<script defer src="js/katex/katex.min.js"></script>
|
||||
<script defer src="js/katex/auto-render.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
renderMathInElement(document.body, {
|
||||
displayMode: false,
|
||||
// customised options
|
||||
// • auto-render specific keys, e.g.:
|
||||
delimiters: [
|
||||
{left: '$$', right: '$$', display: true},
|
||||
{left: '$', right: '$', display: false},
|
||||
{left: "\\[", right: "\\]", display: true},
|
||||
{left: "\\(", right: "\\)", display: false},
|
||||
],
|
||||
// • rendering keys, e.g.:
|
||||
throwOnError : true
|
||||
});
|
||||
});
|
||||
|
||||
///
|
||||
let theme = localStorage.getItem("theme");
|
||||
if ((theme === "light-theme")||(theme==null)) {
|
||||
theme = "light-theme";
|
||||
document.getElementById("themeSwitcher").checked = false;
|
||||
} else if (theme === "dark-theme") {
|
||||
theme = "dark-theme";
|
||||
document.getElementById("themeSwitcher").checked = true;
|
||||
}
|
||||
document.body.className = theme;
|
||||
localStorage.setItem("theme", theme);
|
||||
|
||||
function switchTheme() {
|
||||
theme = localStorage.getItem("theme");
|
||||
if (theme === "light-theme") {
|
||||
theme = "dark-theme";
|
||||
document.getElementById("themeSwitcher").checked = true;
|
||||
} else {
|
||||
theme = "light-theme";
|
||||
document.getElementById("themeSwitcher").checked = false;
|
||||
}
|
||||
document.body.className = theme;
|
||||
localStorage.setItem("theme", theme);
|
||||
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
if (hElem.parentNode.className=="row postThumb") {
|
||||
continue;
|
||||
}
|
||||
hElem.id = hElem.innerHTML.toLowerCase().replace(" ", "-");
|
||||
hElem.innerHTML = "<a style='text-decoration:none;color:black;' href='#"+hElem.id+"'>"+hElem.innerHTML+"</a>";
|
||||
}
|
||||
}
|
||||
tagLinks("h2");
|
||||
tagLinks("h3");
|
||||
tagLinks("h4");
|
||||
tagLinks("h5");
|
||||
</script>
|
||||
<script src="js/mermaid.min.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
343
public/ringsig.html
Normal file
@@ -0,0 +1,343 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta name="description" content="Notes on ring signatures" />
|
||||
<meta charset="utf-8">
|
||||
<title> bLSAG ring signatures overview - arnaucube - blog</title>
|
||||
<meta name="title" content=" bLSAG ring signatures overview - arnaucube - blog">
|
||||
<meta name="description" content="Notes on ring signatures">
|
||||
|
||||
<meta property="og:title" content=" bLSAG ring signatures overview - arnaucube - blog" />
|
||||
<meta property="og:description" content="Notes on ring signatures" />
|
||||
<meta property="og:url" content="https://arnaucube.com/blog/ringsig.html" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:image" content="https://arnaucube.com/blog/" />
|
||||
<meta name="twitter:title" content=" bLSAG ring signatures overview - arnaucube - blog">
|
||||
<meta name="twitter:description" content="Notes on ring signatures">
|
||||
<meta name="twitter:image" content="https://arnaucube.com/blog/">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
<link rel="stylesheet" href="js/katex/katex.min.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- o_gradient_background" -->
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
<input onclick="switchTheme()" type="checkbox" name="onoffswitch" class="onoffswitch-checkbox"
|
||||
id="themeSwitcher">
|
||||
<label class="onoffswitch-label" for="themeSwitcher"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img style="height:5px; width:100%; margin-top:8px;" src="img/gradient-line.jpg" />
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
<div class="container" style="margin-top:40px;max-width:800px;">
|
||||
<h1>bLSAG ring signatures overview</h1>
|
||||
|
||||
<p><em>2022-07-20</em></p>
|
||||
|
||||
<blockquote>
|
||||
<p>Note: I’m not a mathematician, I’m just an amateur on math. These notes are just an attempt to try to sort the notes that I took while learning abut bLSAG.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><br>
|
||||
bLSAG: Back’s Linkable Spontaneous Anonymous Group signatures</p>
|
||||
|
||||
<ul>
|
||||
<li>signer ambiguity</li>
|
||||
<li>linkability</li>
|
||||
<li>unforgeability</li>
|
||||
</ul>
|
||||
|
||||
<h3>Setup</h3>
|
||||
|
||||
<p>Let <span class="math inline">\(G\)</span> be the generator of an EC group.
|
||||
We use a hash function <span class="math inline">\(\mathcal{H}_p\)</span>, which maps to curve points in EC, and a normal hash <span class="math inline">\(\mathcal{H}_n\)</span>, which maps to <span class="math inline">\(\mathbb{Z}_p\)</span>.
|
||||
Signer’s key pair: <span class="math inline">\(k_{\pi}\)</span>, s.t. <span class="math inline">\(K_{\pi} = k_{\pi} \cdot G \in \mathcal{R}\)</span>, with secret index <span class="math inline">\(\pi\)</span>.
|
||||
Set of Public Keys: <span class="math inline">\(\mathcal{R} = \{ K_1, K_2, \ldots, K_n \}\)</span></p>
|
||||
|
||||
<pre><code class="language-python">def new_key():
|
||||
k = F.random_element()
|
||||
K = g * k # g is the generator of the EC group
|
||||
return K
|
||||
</code></pre>
|
||||
|
||||
<h3>Signature</h3>
|
||||
|
||||
<ol>
|
||||
<li><p>compute key image: <span class="math inline">\(\tilde{K} = k_{\pi} \mathcal{H_p} ( K_{\pi}) \in G\)</span></p>
|
||||
|
||||
<pre><code class="language-python">key_image = k * hashToPoint(K)
|
||||
</code></pre></li>
|
||||
|
||||
<li><p>Generate <span class="math inline">\(\alpha \in^R \mathbb{Z}_p\)</span>, and <span class="math inline">\(r_i \in^R \mathbb{Z}_p\)</span>, for <span class="math inline">\(i \in \{1, 2, \ldots, n \}\)</span>, with <span class="math inline">\(i \neq \pi\)</span></p>
|
||||
|
||||
<ul>
|
||||
<li><p><span class="math inline">\(r_i\)</span> is used for the fake responses</p>
|
||||
|
||||
<pre><code class="language-python">a = F.random_element()
|
||||
r = [None] * len(R)
|
||||
for i in range(0, len(R)):
|
||||
if i==pi:
|
||||
continue
|
||||
|
||||
|
||||
r[i] = mod(F.random_element(), p)
|
||||
</code></pre></li>
|
||||
</ul></li>
|
||||
|
||||
<li><p>Compute <span class="math inline">\(c_{\pi + 1} = \mathcal{H}_n ( m, [\alpha G], [\alpha \mathcal{H}_p(K_{\pi})])\)</span></p>
|
||||
|
||||
<pre><code class="language-python">c[pi1] = hash(R, m, a * g, hashToPoint(R[pi]) * a, p)
|
||||
</code></pre></li>
|
||||
|
||||
<li><p>for <span class="math inline">\(i=\pi + 1, \pi +2, \ldots, n, 1, 2, \ldots, \pi -1\)</span>, calculate, replacing <span class="math inline">\(n+1 \rightarrow 1\)</span>
|
||||
$<span class="math inline">\(
|
||||
c_{i+1} = \mathcal{H}_n (m, [r_i G + c_i K_i], [r_i \mathcal{H}_p (K_i) + c_i \tilde{K}])
|
||||
\)</span>$</p>
|
||||
|
||||
<ul>
|
||||
<li>Notice that (from step 3 & 4):<br>
|
||||
<span class="math inline">\(\alpha \mathcal{H}_p (K_{\pi}) = r_{\pi} \mathcal{H}_p (K_{\pi}) + c_{\pi} \cdot (\tilde{K})\)</span>,<br>
|
||||
where <span class="math inline">\(\tilde{K}= k_{\pi} \mathcal{H_p} ( K_{\pi})\)</span>, so:<br>
|
||||
<span class="math inline">\(\alpha \mathcal{H}_p (K_{\pi}) = r_{\pi} \mathcal{H}_p (K_{\pi}) + c_{\pi} \cdot (k_{\pi} \mathcal{H}_p(K_{\pi}))\)</span><br>
|
||||
which is equal to,<br>
|
||||
<span class="math inline">\(\alpha \cdot \mathcal{H}_p (K_{\pi}) = (r_{\pi} + c_{\pi} \cdot k_{\pi}) \cdot \mathcal{H}_p(K_{\pi})\)</span><br>
|
||||
From where we can see: <span class="math inline">\(\alpha = r_{\pi} + c_{\pi} \cdot k_{\pi}\)</span><br>
|
||||
which we can rearrange to
|
||||
<span class="math inline">\(r_{\pi} = \alpha - c_{\pi} \cdot k_{\pi}\)</span>.<br><br></li>
|
||||
</ul>
|
||||
|
||||
<pre><code class="language-python">for j in range(0, len(R)-1):
|
||||
i = mod(pi1+j, len(R))
|
||||
i1 = mod(pi1+j +1, len(R))
|
||||
|
||||
|
||||
c[i1] = hash(R, m, r[i] * g + c[i] * R[i],
|
||||
r[i] * hashToPoint(R[i]) + c[i] * key_image, p)
|
||||
</code></pre></li>
|
||||
|
||||
<li><p>Define <span class="math inline">\(r_{\pi} = \alpha - c_{\pi} k_{\pi} \mod{p}\)</span></p></li>
|
||||
</ol>
|
||||
|
||||
<pre><code class="language-python">r[pi] = mod(a - c[pi] * k, p)
|
||||
</code></pre>
|
||||
|
||||
<p>Signature: <span class="math inline">\(\sigma(m) = (c_1, r_1, \ldots, r_n)\)</span>, with key image <span class="math inline">\(\tilde{K}\)</span> and ring <span class="math inline">\(\mathcal{R}\)</span>.
|
||||
- <span class="math inline">\(len(\sigma(m)) = 1+n\)</span></p>
|
||||
|
||||
<pre><code class="language-python">return [c[0], r]
|
||||
</code></pre>
|
||||
|
||||
<p><br><br><br></p>
|
||||
|
||||
<h4>Step by step (simplified):</h4>
|
||||
|
||||
<div style="overflow:auto;">
|
||||
<div style="width: 60%; float:left; height: 360px; overflow-y:scroll;">
|
||||
|
||||
<img src="img/posts/ring-sig/step00.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step00.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step01.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step02.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step03.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step04.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step05.png" style="width:100%;" />
|
||||
<img src="img/posts/ring-sig/step06.png" style="width:100%;" />
|
||||
|
||||
</div>
|
||||
|
||||
<div style="width: 40%; float:right; margin-top:80px;">
|
||||
|
||||
<ul>
|
||||
<li>Generate $r_i \in^R \mathbb{Z_p}$</li>
|
||||
<li>Compute $c_{i+1}$ from $r_i$</li>
|
||||
<li>Link $r_{\pi}$ with $c_{\pi}$</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p><em>You can scroll down the images through the step-by-step diagrams.</em></p>
|
||||
|
||||
<p><br></p>
|
||||
|
||||
<p>It reminds in some way to the approach to close a box like the one in the picture:
|
||||
<img src="img//posts/ring-sig/box-closed.png" alt="" /></p>
|
||||
|
||||
<p><br><br><br></p>
|
||||
|
||||
<h3>Verification</h3>
|
||||
|
||||
<ol>
|
||||
<li><p>check <span class="math inline">\(p \tilde{K} \stackrel{?}{=} 0\)</span></p>
|
||||
|
||||
<ul>
|
||||
<li>to ensure that <span class="math inline">\(\tilde{K} \in G\)</span> (and not in a cofactor group of <span class="math inline">\(G\)</span>)</li>
|
||||
</ul></li>
|
||||
|
||||
<li><p>for <span class="math inline">\(i = 1, 2, \ldots, n\)</span>, replacing <span class="math inline">\(n+1 \rightarrow 1\)</span>
|
||||
$<span class="math inline">\(
|
||||
c'_{i+1} = \mathcal{H}_n (m, [r_i G + c_i K_i], [r_i \mathcal{H}_p (K_i) + c_i \tilde{K}])
|
||||
\)</span>$</p></li>
|
||||
|
||||
<li><p>check <span class="math inline">\(c_1 \stackrel{?}{=} c'_i\)</span></p>
|
||||
|
||||
<pre><code class="language-python">c[0] = c1
|
||||
for j in range(0, len(R)):
|
||||
i = mod(j, len(R))
|
||||
i1 = mod(j+1, len(R))
|
||||
c[i1] = hash(R, m, r[i] * g + c[i] * R[i],
|
||||
r[i] * hashToPoint(R[i]) + c[i] * key_image, p)
|
||||
|
||||
|
||||
assert c1 == c[0]
|
||||
</code></pre></li>
|
||||
</ol>
|
||||
|
||||
<p><br><br></p>
|
||||
|
||||
<h2>Links</h2>
|
||||
|
||||
<p>Toy implementation:</p>
|
||||
|
||||
<ul>
|
||||
<li>Sage: <a href="https://github.com/arnaucube/math/blob/master/ring-signatures.sage">https://github.com/arnaucube/math/blob/master/ring-signatures.sage</a></li>
|
||||
<li>Rust: <a href="https://github.com/arnaucube/ring-signatures-rs">https://github.com/arnaucube/ring-signatures-rs</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Resources:</p>
|
||||
|
||||
<ul>
|
||||
<li><em>“Zero to Monero”</em> - <a href="https://web.getmonero.org/library/Zero-to-Monero-2-0-0.pdf">https://web.getmonero.org/library/Zero-to-Monero-2-0-0.pdf</a>
|
||||
(section <em>“3.4 Back’s Linkable Spontaneous Anonymous Group (bLSAG) signatures”</em>)</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
style="color:gray;text-decoration:none;"
|
||||
target="_blank">twitter.com/arnaucube</a>
|
||||
</li>
|
||||
<li><a href="https://github.com/arnaucube"
|
||||
style="color:gray;text-decoration:none;"
|
||||
target="_blank">github.com/arnaucube</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="row" style="display:inline-block;">
|
||||
Blog made with <a href="http://github.com/arnaucube/blogo/"
|
||||
target="_blank" style="color: gray;text-decoration:none;">Blogo</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
<script src="js/external-links.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
<script defer src="js/katex/katex.min.js"></script>
|
||||
<script defer src="js/katex/auto-render.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
renderMathInElement(document.body, {
|
||||
displayMode: false,
|
||||
// customised options
|
||||
// • auto-render specific keys, e.g.:
|
||||
delimiters: [
|
||||
{left: '$$', right: '$$', display: true},
|
||||
{left: '$', right: '$', display: false},
|
||||
{left: "\\[", right: "\\]", display: true},
|
||||
{left: "\\(", right: "\\)", display: false},
|
||||
],
|
||||
// • rendering keys, e.g.:
|
||||
throwOnError : true
|
||||
});
|
||||
});
|
||||
|
||||
///
|
||||
let theme = localStorage.getItem("theme");
|
||||
if ((theme === "light-theme")||(theme==null)) {
|
||||
theme = "light-theme";
|
||||
document.getElementById("themeSwitcher").checked = false;
|
||||
} else if (theme === "dark-theme") {
|
||||
theme = "dark-theme";
|
||||
document.getElementById("themeSwitcher").checked = true;
|
||||
}
|
||||
document.body.className = theme;
|
||||
localStorage.setItem("theme", theme);
|
||||
|
||||
function switchTheme() {
|
||||
theme = localStorage.getItem("theme");
|
||||
if (theme === "light-theme") {
|
||||
theme = "dark-theme";
|
||||
document.getElementById("themeSwitcher").checked = true;
|
||||
} else {
|
||||
theme = "light-theme";
|
||||
document.getElementById("themeSwitcher").checked = false;
|
||||
}
|
||||
document.body.className = theme;
|
||||
localStorage.setItem("theme", theme);
|
||||
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
if (hElem.parentNode.className=="row postThumb") {
|
||||
continue;
|
||||
}
|
||||
hElem.id = hElem.innerHTML.toLowerCase().replace(" ", "-");
|
||||
hElem.innerHTML = "<a style='text-decoration:none;color:black;' href='#"+hElem.id+"'>"+hElem.innerHTML+"</a>";
|
||||
}
|
||||
}
|
||||
tagLinks("h2");
|
||||
tagLinks("h3");
|
||||
tagLinks("h4");
|
||||
tagLinks("h5");
|
||||
</script>
|
||||
<script src="js/mermaid.min.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,23 +2,25 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta name="description" content="" />
|
||||
<meta name="description" content="Overview of Langrange Polynomial interpolation and Shamir's secret sharing." />
|
||||
<meta charset="utf-8">
|
||||
<title> Lagrange Polynomial Interpolation and Shamir secret sharing - arnaucube - blog</title>
|
||||
<meta name="title" content=" Lagrange Polynomial Interpolation and Shamir secret sharing - arnaucube - blog">
|
||||
<meta name="description" content="">
|
||||
<meta name="description" content="Overview of Langrange Polynomial interpolation and Shamir's secret sharing.">
|
||||
|
||||
<meta property="og:title" content=" Lagrange Polynomial Interpolation and Shamir secret sharing - arnaucube - blog" />
|
||||
<meta property="og:description" content="" />
|
||||
<meta property="og:description" content="Overview of Langrange Polynomial interpolation and Shamir's secret sharing." />
|
||||
<meta property="og:url" content="https://arnaucube.com/blog/shamir-secret-sharing.html" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:image" content="https://arnaucube.com/blog/" />
|
||||
<meta name="twitter:title" content=" Lagrange Polynomial Interpolation and Shamir secret sharing - arnaucube - blog">
|
||||
<meta name="twitter:description" content="">
|
||||
<meta name="twitter:description" content="Overview of Langrange Polynomial interpolation and Shamir's secret sharing.">
|
||||
<meta name="twitter:image" content="https://arnaucube.com/blog/">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="arnaucube">
|
||||
|
||||
<link rel="icon" type="image/png" href="img/logoArnauCubeFavicon.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -26,7 +28,8 @@
|
||||
|
||||
<!-- highlightjs -->
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/atom-one-dark.css"> -->
|
||||
<link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css">
|
||||
<link rel="stylesheet" href="js/highlightjs/atom-one-light.css">
|
||||
<!-- <link rel="stylesheet" href="js/highlightjs/gruvbox-dark.css"> -->
|
||||
<script src="js/highlightjs/highlight.pack.js"></script>
|
||||
|
||||
<!-- katex -->
|
||||
@@ -39,7 +42,11 @@
|
||||
<nav id="mainNav" class="navbar navbar-default navbar-fixed-top"
|
||||
style="height:50px;font-size:130%;">
|
||||
<div class="container">
|
||||
<a href="/blog" style="color:#000;">Blog index</a>
|
||||
<div style="float:left;">
|
||||
<a href="/blog" style="color:#000;display:inline-block;">Blog index</a>
|
||||
<span style="margin-right:20px; margin-left:20px;">|</span>
|
||||
<a href="/blog/notes.html" style="font-size:90%;color:#000;display:inline-block;">other-notes</a>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<a href="/" style="color:#000;display:inline-block;">arnaucube.com</a>
|
||||
<div class="onoffswitch" style="margin:10px;display:inline-block;" title="change theme">
|
||||
@@ -145,6 +152,9 @@ I(x) = y_2 \cdot l_2(x) + y_4 \cdot l_4(x) + y_5 \cdot l_5(x)\newline
|
||||
|
||||
<footer style="text-align:center; margin-top:100px;margin-bottom:50px;">
|
||||
<div class="container">
|
||||
<br>
|
||||
<a href="/blog">Go to main</a>
|
||||
<br><br>
|
||||
<div class="row">
|
||||
<ul class="list-inline">
|
||||
<li><a href="https://twitter.com/arnaucube"
|
||||
@@ -214,7 +224,7 @@ I(x) = y_2 \cdot l_2(x) + y_4 \cdot l_4(x) + y_5 \cdot l_5(x)\newline
|
||||
console.log(theme);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
<script>
|
||||
function tagLinks(tagName) {
|
||||
var tags = document.getElementsByTagName(tagName);
|
||||
for (var i=0, hElem; hElem = tags[i]; i++) {
|
||||
|
||||