-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide a simple HTML page to compute proof size and time from parameters #22
Closed
Closed
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
a21c969
Introduce interactive web UI to tweak ALBA parameters
abailly 9b9048b
Compute size of proof from size of items
abailly fbe337e
Compute proof time given some number of items
abailly c526539
Document chart and output values computation
abailly 2f3372f
Move parameters simulation in generated mdbook content
abailly fca57e1
Remove incorrect computation of CPU time
abailly 596484e
Update field label
abailly 3854698
Separate introduction on ALBA guarantees from explanation of algorithm
abailly 9079c7e
Update text
abailly 5494b18
Update docs/src/intro.md
d831599
Update docs/src/simulation.md
e36018c
Update docs/src/simulation.md
7358aba
Update docs/src/simulation.md
36e620e
Update docs/alba.js
fb3bbb9
Update docs/alba.js
0a08b6a
Update docs/alba.js
93e3e7b
Update docs/src/simulation.md
edb3c85
Update docs/src/simulation.md
6794ee2
Address review comments
abailly File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
.row { | ||
display: flex; | ||
flex-wrap: wrap; | ||
flex-direction: row; | ||
padding: 0.2em; | ||
} | ||
|
||
.col { | ||
display: flex; | ||
flex-direction: column; | ||
padding: 0.2em; | ||
} | ||
|
||
.col-md-2 { | ||
display: flex; | ||
flex: 2; | ||
} | ||
|
||
.col-md-3 { | ||
display: flex; | ||
flex: 0 0 auto; | ||
} | ||
|
||
.col-md-4 { | ||
display: flex; | ||
flex: 4; | ||
} | ||
|
||
.col-md-8 { | ||
display: flex; | ||
flex: 8; | ||
} | ||
|
||
label { | ||
width: 100%; | ||
height: 1.4em; | ||
display: block; | ||
} | ||
|
||
input { | ||
text-align: right; | ||
font-family: monospace; | ||
} | ||
|
||
.help { | ||
display: none; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
document.addEventListener('DOMContentLoaded', () => { | ||
|
||
const lam = 128; | ||
|
||
const node = document.getElementById('main_chart'); | ||
const n_p = document.getElementById('n_p'); | ||
const n_f = document.getElementById('n_f'); | ||
const item = document.getElementById('item'); | ||
const proof_size = document.getElementById('proof_size'); | ||
const n = document.getElementById('n'); | ||
const proof_proba = document.getElementById('proof_proba'); | ||
|
||
function U(n_p, n_f) { | ||
return Math.ceil((lam + Math.log2(lam) + 5 - Math.log2(Math.log2(Math.E))) / Math.log2(n_p / n_f)); | ||
}; | ||
|
||
function probabilityOfProof(u, n_p, n_f, x) { | ||
// from https://github.com/cardano-scaling/alba/discussions/17 | ||
|
||
S_1_bot = n_p / (17 ** 2 / (9 * Math.log2(Math.E)) * u ** 2) - 7 < 1; | ||
S_2_bot = n_p / (17 ** 2 / (9 * Math.log2(Math.E)) * u ** 2) - 2 < 1; | ||
|
||
if (!S_1_bot && !S_2_bot) { | ||
throw Error("S_1_bot or S_2_bot"); | ||
} | ||
|
||
const d = Math.ceil(32 * Math.log(12) * u); | ||
const q = 2 * Math.log(12) / d; | ||
const r = Math.ceil(lam); | ||
|
||
return Math.min(r * (x / n_p) ** u * d * q, 1); | ||
}; | ||
|
||
// Returns updated labels and data | ||
function updatedData() { | ||
const data = []; | ||
const labels = []; | ||
const n_p_v = Number(n_p.value); | ||
const n_f_v = Number(n_f.value); | ||
const u = U(n_p_v, n_f_v); | ||
// number of points | ||
const length = (n_p_v - n_f_v) / 10; | ||
|
||
for (var i = 0; i < length; i++) { | ||
const y = (i * 10) + n_f_v; | ||
labels.push(y); | ||
data.push(probabilityOfProof(u, n_p_v, n_f_v, y)); | ||
} | ||
|
||
return [labels, data]; | ||
} | ||
|
||
const [labels, data] = updatedData(); | ||
|
||
// throughput chart | ||
const chart = new Chart(node, { | ||
title: { | ||
text: "Probabiliy of making a proof" | ||
}, | ||
data: { | ||
// N.B.: Make sure colors are picked from an inclusive color palette. | ||
// See for instance: https://medium.com/@allieofisher/inclusive-color-palettes-for-the-web-bbfe8cf2410e | ||
labels, | ||
datasets: [ | ||
{ | ||
type: 'line', | ||
label: "proof probability", | ||
data, | ||
function: probabilityOfProof, | ||
backgroundColor: '#6FDE6E', | ||
borderColor: '#6FDE6E', | ||
fill: false | ||
} | ||
] | ||
}, | ||
options: { | ||
scales: { | ||
y: { | ||
type: 'logarithmic', | ||
min: 0, | ||
ticks: { | ||
stepSize: 0.0001, | ||
autoSkip: true, | ||
callback: (val) => (val.toExponential(1)) | ||
} | ||
}, | ||
x: { | ||
type: 'linear', | ||
title: { | ||
text: 'n', | ||
display: true | ||
}, | ||
} | ||
} | ||
} | ||
}); | ||
|
||
function updateProofSize() { | ||
const n_p_v = Number(n_p.value); | ||
const n_f_v = Number(n_f.value); | ||
const single = Number(item.value); | ||
const u = U(n_p_v, n_f_v); | ||
proof_size.value = u * single; | ||
} | ||
|
||
function updateProofProba() { | ||
const n_p_v = Number(n_p.value); | ||
const n_f_v = Number(n_f.value); | ||
const n_v = Number(n.value); | ||
const u = U(n_p_v, n_f_v); | ||
const proba = probabilityOfProof(u, n_p_v, n_f_v, n_v); | ||
// expected prover time is n_p + O (u^2), we neglect the n_p part here | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
proof_proba.value = proba.toExponential(4); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confused about what this does. |
||
} | ||
|
||
function updateChart() { | ||
const [labels, data] = updatedData(); | ||
chart.data.labels = labels; | ||
chart.data.datasets[0].data = data; | ||
chart.update(); | ||
updateProofSize(); | ||
updateProofProba(); | ||
}; | ||
|
||
n_p.addEventListener('change', updateChart); | ||
n_f.addEventListener('change', updateChart); | ||
item.addEventListener('change', updateChart); | ||
n.addEventListener('change', updateProofProba); | ||
|
||
updateProofSize(); | ||
updateProofProba(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
# Summary | ||
|
||
- [Introduction](./intro.md) | ||
- [How it works?](./algorithm.md) | ||
- [Benchmarks](./benchmarks.md) | ||
- [Simulation](./simulation.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Proving | ||
|
||
Here is an alternative graphical representation of how ALBA certificates are produced, using the basic construction. We start with a set denote \\(S_p\\) of elements such that each is _unique_ and its availability can be asserted by a verifier through some predicate (called \\(R\\)) in the paper. | ||
|
||
> **Note**: The \\(S_p\\) set can be smaller than the expected maximum number of elements we want to build a proof on, with a lower bound on \\(n_f\\) the number of expected honest elements. | ||
|
||
![Initial set](proving-0.jpg) | ||
|
||
The first step is to construct the cartesian product of each element of \\(S_p\\), here called \\(a\\) through \\(k\\), with all the integers lower than some parameter \\(d\\), yielding a set of size \\(\|S_p\| \times d\\) | ||
|
||
![Initial tupling](proving-1.jpg) | ||
|
||
From this set, we pseudo-randomly select \\(n_p\\) pairs using a "random oracle" \\(\mathbb{H}\\). \\(\mathbb{H}\\) is effectively just a hash function and to select the adequate number of pairs we pick those with a hash value modulo \\(n_p\\) equals to 0, yielding a set of size roughly \\(n_p\\) of pair of an integer and some item in \\(S_p\\). | ||
|
||
> **Note**: The ratio \\(n_p / n_f\\) is a key factor when setting the needed length of the proof. | ||
|
||
![Selecting pairs](proving-2.jpg) | ||
|
||
We then expand the set again, creating triples of an integer and 2 elements from \\(S_p\\) through a cartesian product between the selected pairs and the initial set, yielding a set of size \\(\|S_p\| \times n_p\\). | ||
|
||
![Expanding set](proving-3.jpg) | ||
|
||
And we again pseudo-randomly select \\(n_p\\) elements from this new set using the same function \\(\mathbb{H}\\), yielding a set of triples of approximate size \\(n_p\\) | ||
|
||
![Selecting triples](proving-4.jpg) | ||
|
||
This process is iterated \\(n\\) times according to the protocol parameters (see the paper or [the code](https://github.com/cardano-scaling/alba/blob/8893e4b2de2cb9d74f135ec4535fbfca6acf83d3/src/ALBA.hs#L162) for details on how these parameters are computed), yielding a set of (roughly) \\(n_p\\) tuples of length \\(n+1\\) where each tuple is some "random" integer along with \\(n\\) items from \\(S_p\\). | ||
|
||
The last stage consists in applying a function \\(\mathbb{H}_1\\) to select _one_ element from this set which is the final _proof_. | ||
|
||
![Selecting proof](proving-5.jpg) | ||
|
||
## Verifying | ||
|
||
Verifying a given proof \\(P\\) is straightforward. Given the known share of honest items \\(n_p\\) and a security parameter \\(\lambda\\) (set at 128 in the paper) controlling the exponentially decaying probability a proof with dishonest items can be constructed, the verifier needs to check: | ||
|
||
* The sequence of hashes from the items in the proof are all 0 modulo \\(n_p\\), | ||
* The value of \\(H_1\\) for the whole sequence is 0 modulo some derived parameter \\(q\\), | ||
* And of course that each item in the sequence is valid w.r.t. the predicate \\(R\\). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,17 @@ | ||
# Introduction | ||
|
||
_Approximate Lower Bound Arguments_ are a form of cryptographic certificates that allow a _prover_ to convince a _verifier_ they know some large set of elements by providing only a small subset of those elements. This excellent [X thread](https://x.com/Quantumplation/status/1783188333046255997) provides a good intuition on why ALBAs are useful and how they work, and details of the theory behind this construction are beyond the scope of this introduction and can be found in the paper. | ||
## Definition | ||
|
||
### Proving | ||
_Approximate Lower Bound Arguments_ are a form of cryptographic certificates that allow a _prover_ to convince a _verifier_ they know some set of elements by providing only a small subset of those elements. More formally, given some set of elements, and some bounds \\(n_p\\) and \\(n_f\\), where \\(n_p > n_f\\), about the size of this set, ALBA provides an algorithm that allows to build a _proof_ they know _at least_ \\(n_f\\) elements, where the proof size is a constant value derived from the \\(\frac{n_p}{n_f}\\) ratio. | ||
|
||
Here is an alternative graphical representation of how ALBA certificates are produced, using the basic construction. We start with a set denote \\(S_p\\) of elements such that each is _unique_ and its availability can be asserted by a verifier through some predicate (called \\(R\\)) in the paper. | ||
The algorithm provides the following guarantees, given the prover has \\(S_p\\) elements and a security parameter \\(\lambda\\): | ||
|
||
> **Note**: The \\(S_p\\) set can be smaller than the expected maximum number of elements we want to build a proof on, with a lower bound on \\(n_p\\) the number of expected honest elements. | ||
* if \\(|S_p| \geq n_p\\) then the prover has a probability lower than \\(2^{-\lambda}\\) of _failure_ to build a proof, or in other words they are sure to find one, | ||
* if \\(|S_p| \leq n_f\\) then the prover has a probability lower than \\(2^{-\lambda}\\) of _success_ to build a proof, | ||
* in between those 2 bounds, the probability of being able to build a proof drops exponentially (see our [simulation](./simulation.md) page for a graphical exploration of this probability). | ||
|
||
![Initial set](proving-0.jpg) | ||
Details of the theory behind this construction are beyond the scope of this introduction and can be found in the paper. | ||
|
||
The first step is to construct the cartesian product of each element of \\(S_p\\), here called \\(a\\) through \\(k\\), with all the integers lower than some parameter \\(d\\), yielding a set of size \\(\|S_p\| \times d\\) | ||
## Usefulness | ||
|
||
![Initial tupling](proving-1.jpg) | ||
|
||
From this set, we pseudo-randomly select \\(n_p\\) pairs using a "random oracle" \\(\mathbb{H}\\). \\(\mathbb{H}\\) is effectively just a hash function and to select the adequate number of pairs we pick those with a hash value modulo \\(n_p\\) equals to 0, yielding a set of size roughly \\(n_p\\) of pair of an integer and some item in \\(S_p\\). | ||
|
||
> **Note**: The ratio \\(n_p / n_f\\) is a key factor when setting the needed length of the proof. | ||
|
||
![Selecting pairs](proving-2.jpg) | ||
|
||
We then expand the set again, creating triples of an integer and 2 elements from \\(S_p\\) through a cartesian product between the selected pairs and the initial set, yielding a set of size \\(\|S_p\| \times n_p\\). | ||
|
||
![Expanding set](proving-3.jpg) | ||
|
||
And we again pseudo-randomly select \\(n_p\\) elements from this new set using the same function \\(\mathbb{H}\\), yielding a set of triples of approximate size \\(n_p\\) | ||
|
||
![Selecting triples](proving-4.jpg) | ||
|
||
This process is iterated \\(n\\) times according to the protocol parameters (see the paper or [the code](https://github.com/cardano-scaling/alba/blob/8893e4b2de2cb9d74f135ec4535fbfca6acf83d3/src/ALBA.hs#L162) for details on how these parameters are computed), yielding a set of (roughly) \\(n_p\\) tuples of length \\(n+1\\) where each tuple is some "random" integer along with \\(n\\) items from \\(S_p\\). | ||
|
||
The last stage consists in applying a function \\(\mathbb{H}_1\\) to select _one_ element from this set which is the final _proof_. | ||
|
||
![Selecting proof](proving-5.jpg) | ||
|
||
|
||
### Verifying | ||
|
||
[Verifying](https://github.com/cardano-scaling/alba/blob/8893e4b2de2cb9d74f135ec4535fbfca6acf83d3/src/ALBA.hs#L259) a given proof \\(P\\) is straightforward. Given the known share of honest items \\(n_p\\) and a security parameter \\(\lambda\\) (set at 128 in the paper) controlling the exponentially decaying probability a proof with dishonest items can be constructed, the verifier needs to check: | ||
|
||
* The sequence of hashes from the items in the proof are all 0 modulo \\(n_p\\), | ||
* The value of \\(H_1\\) for the whole sequence is 0 modulo some derived parameter \\(q\\), | ||
* And of course that each item in the sequence is valid w.r.t. the predicate \\(R\\). | ||
This excellent [X thread](https://x.com/Quantumplation/status/1783188333046255997) provides a good intuition on why ALBAs is useful and how it works. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# ALBA Parameters Simulation | ||
|
||
ALBA provides strong security guarantees about the capability to generate a proof given some number of items \\(n\\): | ||
|
||
* a honest prover with at least \\(n_p\\) items has a probability of | ||
failing to generate a proof lower than \\(2^{-128}\\), | ||
* symetrically, a (dishonest) prover with at most \\(n_f\\) items | ||
has probability of succeeding to generate a proof lower than | ||
\\(2^{-128}\\). | ||
|
||
This page provides a simple and user-friendly way of estimating how | ||
various ALBA parameters impact the size of the proof and probability | ||
of having a proof, given a number of items \\(n\\) varying between | ||
the two parameters' bounds. It is expected to be a quick way to | ||
estimate what would be "good" values for those parameters in a | ||
specific context, depending on security requirements and expected | ||
adversarial share. | ||
|
||
One can define: | ||
|
||
* \\(n_p\\): The size of the _honest set_ of items. | ||
* \\(n_f\\): The size of the _faulty set_ of items. \\(n_f\\) must be lower than \\(n_p\\). | ||
* Item size: The size of a single item, this is used to compute the full size of a proof. | ||
* \\(n\\): The number of items actually available to an adversary, or put differently, how much adversarial stake should we expect. | ||
|
||
From these parameters, we display a chart showing the probability of | ||
an adversary being able to compute a single valid proof, given some | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
number of items \\(n\\) available between \\(n_p\\) and | ||
\\(n_f\\). The formula used, initially proposed in this [GitHub | ||
discussion](https://github.com/cardano-scaling/alba/discussions/17) | ||
is: | ||
|
||
\\[ | ||
r \cdot {\left( \frac{n}{n_p} \right)}^u\cdot qd | ||
\\] | ||
|
||
where _u_, _r_, _q_, and _d_ are defined in the aforementioned | ||
section of the paper. Note the vertical axis' scale is logarithmic. | ||
|
||
We also display two specific values: | ||
|
||
* the size of the proof for the given \\(n_p/n_f\\) ratio and individual | ||
item size, which is given by the formula from section 3.2.2, | ||
Corollary 3, from the [ALBA | ||
paper](https://iohk.io/en/research/library/papers/approximate-lower-bound-arguments/), | ||
* the probability of having a proof for some specific number of \\(n\\) (computed. | ||
|
||
<div class="col col-md-8"> | ||
<div class="row"> | ||
<div id="chart" class="row" style="width: 100%; margin: auto;" > | ||
<canvas id="main_chart"></canvas> | ||
</div> | ||
</div> | ||
<div class="row g-3" style="margin: auto;"> | ||
<div class="col col-md-3"> | ||
<label for="n_p" class="form-label">\(n_p\)<span class="help" data-bs-toggle="tooltip" title="Expected number of honest set of items.">?</span></label> | ||
<input type="number" step="10" class="form-control" id="n_p" value="800"> | ||
</div> | ||
<div class="col col-md-3"> | ||
<label for="n_f" class="form-label">\(n_f\)<span class="help" data-bs-toggle="tooltip" title="Expected number of faulty set of items.">?</span></label> | ||
<input type="number" step="10" class="form-control" id="n_f" value="400"> | ||
</div> | ||
<div class="col col-md-3"> | ||
<label for="item" class="form-label">Item size<span class="help" data-bs-toggle="tooltip" title="Size of a single item.">?</span></label> | ||
<input type="number" step="10" class="form-control" id="item" value="600"> | ||
</div> | ||
<div class="col col-md-3"> | ||
<label for="proof_size" class="form-label">Proof size<span class="help" data-bs-toggle="tooltip" title="Total size of proof.">?</span></label> | ||
<input type="number" class="form-control" id="proof_size" disabled> | ||
</div> | ||
</div> | ||
<div class="row g-3" style="width: 95%; margin: auto;"> | ||
<div class="col col-md-3"> | ||
<label for="n" class="form-label">\(n\)<span class="help" data-bs-toggle="tooltip" title="Number of items actually available.">?</span></label> | ||
<input type="number" step="10" class="form-control" id="n" value="700"> | ||
</div> | ||
<div class="col col-md-3"> | ||
<label for="proof_proba" class="form-label">Proof probability<span class="help" data-bs-toggle="tooltip" title="Probability of having a proof for some number of items.">?</span></label> | ||
<input type="number" class="form-control" id="proof_proba" disabled> | ||
</div> | ||
<div class="col-md-3"/> | ||
</div> | ||
</div> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alert
or sth like that?n_p
values (where this error is currently thrown).(Doesn't necessarily have to happen in this PR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I copy/pasted your code. I think it's good enough for now but obviously throwing exceptions in user-facing code is not great. I don't like
alert()
but can find a good substitute.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you throw an error and not update the d/q/r parameters depending on S1 and S2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for this simulation we can just use the parameters for the "small case". They in fact work for all cases, it's just, the prover will not have a good worst-case running time. Then we don't need to worry about S_1_bot, etc.
We can borrow the math code from Raphael's implementation.
https://github.com/cardano-scaling/alba/pull/33/files#diff-b0bad697f839908964cc4e445cd9c87a76b4a5f84da347b24a426b61b7d09322R127