Skip to content

Commit bcefe97

Browse files
committed
Documented functions and structures
1 parent dcf8561 commit bcefe97

24 files changed

+145
-2
lines changed

crypto-benchmarks.rs/benches/fait_accompli_bench.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Criterion benchmarks for Fait Accompli.
2+
13
use criterion::{criterion_group, criterion_main, Criterion};
24
use quickcheck::{Arbitrary, Gen};
35
use std::collections::BTreeMap;

crypto-benchmarks.rs/benches/serialization_bench.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Criterion benchmarks for serialization and deserialization.
2+
13
use criterion::{criterion_group, criterion_main, Criterion};
24
use quickcheck::{Arbitrary, Gen};
35

crypto-benchmarks.rs/benches/sortition_bench.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Criterion benchmarks for sortition.
2+
13
use criterion::{criterion_group, criterion_main, Criterion};
24
use num_bigint::BigInt;
35
use num_rational::Ratio;

crypto-benchmarks.rs/benches/vote_bench.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Criterion benchmarks for voting.
2+
13
use criterion::{criterion_group, criterion_main, Criterion};
24
use leios_crypto_benchmarks::cert::*;
35
use leios_crypto_benchmarks::registry::{arbitrary_pools, PersistentId, Registry};

crypto-benchmarks.rs/benches/vrf_bench.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Criterion benchmarks for VRF.
2+
13
use criterion::{criterion_group, criterion_main, Criterion};
24

35
use leios_crypto_benchmarks::vrf::{sk_random, sk_to_pk_point, vrf_prove, vrf_verify};

crypto-benchmarks.rs/src/bls_util.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
//! Low-level utility functions for BLS operations not supported by the `blst` library.
2+
13
use blst::min_sig::*;
24
use blst::*;
35
use num_bigint::{BigInt, Sign};
46
use num_rational::Ratio;
57
use num_traits::FromPrimitive;
68

9+
/// Apply a function to a public key (i.e., to a point in G2).
710
pub fn pk_transform(f: &dyn Fn(blst_p2) -> blst_p2, pk: &PublicKey) -> PublicKey {
811
let mut point: blst_p2 = blst_p2::default();
912
unsafe {
@@ -24,6 +27,7 @@ pub fn pk_transform(f: &dyn Fn(blst_p2) -> blst_p2, pk: &PublicKey) -> PublicKey
2427
}
2528
}
2629

30+
/// Apply a function to a signature (i.e., to a point in G1).
2731
pub fn sig_transform(f: &dyn Fn(blst_p1) -> blst_p1, sig: &Signature) -> Signature {
2832
let mut point: blst_p1 = blst_p1::default();
2933
unsafe {
@@ -44,6 +48,7 @@ pub fn sig_transform(f: &dyn Fn(blst_p1) -> blst_p1, sig: &Signature) -> Signatu
4448
}
4549
}
4650

51+
/// Convert a signature to a rational number between zero and one.
4752
pub fn sig_to_rational(sig: &Signature) -> Ratio<BigInt> {
4853
let bytes: [u8; 48] = sig.to_bytes();
4954
let mut hashed: [u8; 32] = [0; 32];

crypto-benchmarks.rs/src/bls_vote.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1+
//! Low-level operations on BLS votes.
2+
//!
3+
//! ![Figure 7 (BLS)](../../../../figure-7-bls.png)
4+
//!
5+
//! ![Figure 8 (voting)](../../../../figure-8-voting.png)
6+
17
use blst::min_sig::*;
28
use blst::*;
39
use rand::RngCore;
410

511
use crate::bls_util::*;
612

13+
/// An empty bytestring.
714
const EMPTY: [u8; 0] = [];
815

16+
/// The domain separator for Leios.
917
const DST: &[u8; 5] = b"Leios";
1018

19+
/// Generate a secret BLS scalar.
1120
pub fn gen_key() -> SecretKey {
1221
let mut rng: rand::prelude::ThreadRng = rand::thread_rng();
1322
let mut ikm: [u8; 32] = [0u8; 32];
@@ -16,12 +25,14 @@ pub fn gen_key() -> SecretKey {
1625
SecretKey::key_gen(&ikm, info).unwrap()
1726
}
1827

28+
/// Create a proof of possession from a secret key `sk`, namely $\mu_1$ and $\mu_2$ of [Figure 8 (voting)](index.html).
1929
pub fn make_pop(sk: &SecretKey) -> (Signature, Signature) {
2030
let m1: [u8; 192] = sk.sk_to_pk().serialize();
2131
let m2 = EMPTY;
2232
(sk.sign(&m1, DST, b"PoP"), sk.sign(&m2, DST, &EMPTY))
2333
}
2434

35+
/// Verify the the proof of possession, namely $\mu_1$ and $\mu_2$ of [Figure 8 (voting)](index.html), for a public key `pk`.
2536
pub fn check_pop(pk: &PublicKey, mu1: &Signature, mu2: &Signature) -> bool {
2637
let m1: [u8; 192] = pk.serialize();
2738
let m2 = EMPTY;
@@ -30,29 +41,35 @@ pub fn check_pop(pk: &PublicKey, mu1: &Signature, mu2: &Signature) -> bool {
3041
result1 == BLST_ERROR::BLST_SUCCESS && result2 == BLST_ERROR::BLST_SUCCESS
3142
}
3243

44+
/// Sign the message `m` in the election `eid` using the secret key `sk`.
3345
pub fn gen_sig(sk: &SecretKey, eid: &[u8], m: &[u8]) -> Signature {
3446
sk.sign(m, DST, eid)
3547
}
3648

49+
/// Verify a signature `vs` on the message `m` in the election `eid` for the public key `pk`.
3750
pub fn verify_sig(pk: &PublicKey, eid: &[u8], m: &[u8], vs: &Signature) -> bool {
3851
let result_m = vs.verify(true, m, DST, eid, pk, false);
3952
result_m == BLST_ERROR::BLST_SUCCESS
4053
}
4154

55+
/// Sign the election `eid` with the secret key `sk`.
4256
pub fn gen_sigma_eid(sk: &SecretKey, eid: &[u8]) -> Signature {
4357
sk.sign(&EMPTY, DST, eid)
4458
}
4559

60+
/// Create a vote for the message `m` in the election `eid` using the secret key `sk`.
4661
pub fn gen_vote(sk: &SecretKey, eid: &[u8], m: &[u8]) -> (Signature, Signature) {
4762
(sk.sign(&EMPTY, DST, eid), sk.sign(m, DST, eid))
4863
}
4964

65+
/// Verify the vote `vs` for the message `m` in the election `eid` for the public key `pk`.
5066
pub fn verify_vote(pk: &PublicKey, eid: &[u8], m: &[u8], vs: &(Signature, Signature)) -> bool {
5167
let result_eid = vs.0.verify(true, &EMPTY, DST, eid, pk, true);
5268
let result_m = vs.1.verify(true, m, DST, eid, pk, false);
5369
result_eid == BLST_ERROR::BLST_SUCCESS && result_m == BLST_ERROR::BLST_SUCCESS
5470
}
5571

72+
/// Hash an array of signatures `sigma_eids` and `sigma_ms`.
5673
fn hash_sigs(sigma_eids: &[&Signature], sigma_ms: &[&Signature]) -> [u8; 32] {
5774
let mut sigmas: Vec<&Signature> = Vec::new();
5875
sigmas.extend(sigma_eids);
@@ -65,6 +82,7 @@ fn hash_sigs(sigma_eids: &[&Signature], sigma_ms: &[&Signature]) -> [u8; 32] {
6582
}
6683
}
6784

85+
/// Hash an integer `i` with a previous hash `h`.
6886
fn hash_index(i: i32, h: &[u8; 32]) -> [u8; 32] {
6987
let mut msg: [u8; 36] = [0; 36];
7088
let ii: [u8; 4] = i.to_ne_bytes();
@@ -80,12 +98,14 @@ fn hash_index(i: i32, h: &[u8; 32]) -> [u8; 32] {
8098
}
8199
}
82100

101+
/// Create the signatures for a certificate from the individual vote signatures `vss`.
83102
pub fn gen_cert(vss: &[&(Signature, Signature)]) -> Result<(Signature, Signature), BLST_ERROR> {
84103
let sigma_eids: Vec<&Signature> = vss.iter().map(|vs| &vs.1).collect();
85104
let sigma_ms: Vec<&Signature> = vss.iter().map(|vs| &vs.1).collect();
86105
gen_cert_fa(&sigma_eids, &sigma_ms)
87106
}
88107

108+
/// Verify the contents of certificate signatures `cs` for the message `m` in election `eid`, given the vote signatures `vss`.
89109
pub fn verify_cert(
90110
pks: &[&PublicKey],
91111
eid: &[u8],
@@ -129,6 +149,7 @@ pub fn verify_cert(
129149
}
130150
}
131151

152+
/// Create certificate signatures including both sortition and message signing signatures.
132153
pub fn gen_cert_fa(
133154
sigma_eids: &[&Signature],
134155
sigma_ms: &[&Signature],
@@ -161,6 +182,7 @@ pub fn gen_cert_fa(
161182
}
162183
}
163184

185+
/// Create cerificate signatures including only message signing signatures.
164186
pub fn gen_cert_fa_pure(sigma_ms: &[&Signature]) -> Result<Signature, BLST_ERROR> {
165187
let result_m = AggregateSignature::aggregate(sigma_ms, true);
166188
match result_m {
@@ -169,6 +191,7 @@ pub fn gen_cert_fa_pure(sigma_ms: &[&Signature]) -> Result<Signature, BLST_ERROR
169191
}
170192
}
171193

194+
/// Verify cerificate sigantures according to [Figure 8 (voting)](index.html).
172195
pub fn verify_cert_fa(
173196
pks: &[&PublicKey],
174197
pks_nonpersistent: &[&PublicKey],
@@ -212,6 +235,7 @@ pub fn verify_cert_fa(
212235
}
213236
}
214237

238+
/// Verify signatures for a message, without verifying sortition.
215239
pub fn verify_cert_fa_pure(
216240
pks: &[&PublicKey],
217241
eid: &[u8],

crypto-benchmarks.rs/src/cert.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! High-level operations on certificates.
2+
13
use blst::min_sig::*;
24
use quickcheck::{Arbitrary, Gen};
35
use serde::{Deserialize, Serialize};
@@ -10,6 +12,7 @@ use crate::registry::{PersistentId, Registry};
1012
use crate::sortition::voter_check;
1113
use crate::vote::{do_voting, Vote};
1214

15+
/// A certificate records the election and EB information along with the persistent voters who voted and the proofs for the non-persistent voters. It contains two aggregate signatures, one for sortition and other for the votes themselves.
1316
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
1417
pub struct Cert {
1518
pub eid: Eid,
@@ -20,6 +23,7 @@ pub struct Cert {
2023
pub sigma_tilde_m: Sig,
2124
}
2225

26+
/// Generate an arbitrary certificate.
2327
pub fn arbitrary_cert(g: &mut Gen, reg: &Registry) -> Cert {
2428
let eid = Eid::arbitrary(g);
2529
let eb = EbHash::arbitrary(g);
@@ -33,6 +37,7 @@ impl Arbitrary for Cert {
3337
}
3438
}
3539

40+
/// It's convenient to have a data structure for holding certificate information as it is being built.
3641
#[derive(Default)]
3742
struct TraverseVote<'a> {
3843
pub eids: HashSet<&'a Eid>,
@@ -43,6 +48,7 @@ struct TraverseVote<'a> {
4348
pub sigma_ms: Vec<&'a Signature>,
4449
}
4550

51+
/// Add one vote to a certification that is being constructed.
4652
fn traverse_vote<'a>(reg: &'a Registry, t: &mut TraverseVote<'a>, vote: &'a Vote) -> Option<()> {
4753
match vote {
4854
Vote::Persistent {
@@ -74,6 +80,7 @@ fn traverse_vote<'a>(reg: &'a Registry, t: &mut TraverseVote<'a>, vote: &'a Vote
7480
}
7581
}
7682

83+
/// Test that a hash set is a singleton.
7784
fn unique<X>(xs: &HashSet<X>) -> Option<&X> {
7885
if xs.len() == 1 {
7986
xs.iter().next()
@@ -82,6 +89,7 @@ fn unique<X>(xs: &HashSet<X>) -> Option<&X> {
8289
}
8390
}
8491

92+
/// Generate a certificate for the specified votes.
8593
pub fn gen_cert(reg: &Registry, votes: &[Vote]) -> Option<Cert> {
8694
let mut t: TraverseVote = TraverseVote::default();
8795
let _ = votes
@@ -113,6 +121,7 @@ pub fn gen_cert(reg: &Registry, votes: &[Vote]) -> Option<Cert> {
113121
}
114122
}
115123

124+
/// Verify a certificate using the information in the voter registry.
116125
pub fn verify_cert(reg: &Registry, cert: &Cert) -> bool {
117126
let pks_persistent: Vec<&PublicKey> = cert
118127
.persistent_voters
@@ -154,6 +163,7 @@ pub fn verify_cert(reg: &Registry, cert: &Cert) -> bool {
154163
}
155164
}
156165

166+
/// Compute the total weight (i.e., stake fraction) of the persistent votes in a certificate.
157167
fn weigh_persistent(reg: &Registry, cert: &Cert) -> Option<CoinFraction> {
158168
let weight: Option<Coin> = cert.persistent_voters.iter().try_fold(0, |acc, pid| {
159169
reg.persistent_pool
@@ -163,6 +173,7 @@ fn weigh_persistent(reg: &Registry, cert: &Cert) -> Option<CoinFraction> {
163173
weight.map(|total| CoinFraction::from_coins(total, 1))
164174
}
165175

176+
/// Compute the total weight (i.e., stake fraction) of the non-persistent votes in a certificate.
166177
fn weigh_nonpersistent(reg: &Registry, cert: &Cert) -> Option<CoinFraction> {
167178
let nonpersistent_voters = reg.voters - cert.persistent_voters.len();
168179
let weight: Option<usize> =
@@ -184,6 +195,7 @@ fn weigh_nonpersistent(reg: &Registry, cert: &Cert) -> Option<CoinFraction> {
184195
})
185196
}
186197

198+
/// Compute the total weight (i.e., stake fraction) of the votes in a certificate.
187199
pub fn weigh_cert(reg: &Registry, cert: &Cert) -> Option<CoinFraction> {
188200
let persistent_weight = weigh_persistent(reg, cert)?.to_ratio();
189201
let nonpersistent_weight = weigh_nonpersistent(reg, cert)?.to_ratio();

crypto-benchmarks.rs/src/fait_accompli.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Fait Accompli operations.
2+
13
use num_bigint::BigInt;
24
use num_rational::Ratio;
35
use num_traits::{One, Zero};
@@ -7,6 +9,7 @@ use std::collections::BTreeMap;
79

810
use crate::primitive::{Coin, CoinFraction, PoolKeyhash};
911

12+
/// Fait Accompli sortition results in a committee of persistent and non-persistent voters.
1013
#[derive(Clone, Debug, Serialize, Deserialize)]
1114
pub struct FaSortition {
1215
pub n_persistent: usize,
@@ -17,6 +20,7 @@ pub struct FaSortition {
1720
}
1821

1922
impl FaSortition {
23+
/// Perform Fait Accompli sortiion on the stake distribution `pools` and target committee size `n`.
2024
pub fn fait_accompli(pools: &BTreeMap<PoolKeyhash, Coin>, n: usize) -> Self {
2125
let zero: Ratio<BigInt> = Ratio::from_integer(BigInt::zero());
2226
let (s, p): (Vec<Ratio<BigInt>>, Vec<PoolKeyhash>) = sort_stake(pools);
@@ -57,6 +61,7 @@ impl FaSortition {
5761
}
5862
}
5963

64+
/// Sort stake pools in order of decreasing stake.
6065
fn sort_stake(pools: &BTreeMap<PoolKeyhash, Coin>) -> (Vec<Ratio<BigInt>>, Vec<PoolKeyhash>) {
6166
let mut sp: Vec<(Ratio<BigInt>, &PoolKeyhash)> = pools
6267
.iter()
@@ -67,6 +72,7 @@ fn sort_stake(pools: &BTreeMap<PoolKeyhash, Coin>) -> (Vec<Ratio<BigInt>>, Vec<P
6772
sp.into_iter().unzip()
6873
}
6974

75+
/// Sum stake fractions.
7076
fn sum_stake(s: &[Ratio<BigInt>]) -> Vec<Ratio<BigInt>> {
7177
let zero: Ratio<BigInt> = Ratio::from_integer(BigInt::zero());
7278
let (mut rho, _): (Vec<Ratio<BigInt>>, Ratio<BigInt>) =
@@ -81,6 +87,7 @@ fn sum_stake(s: &[Ratio<BigInt>]) -> Vec<Ratio<BigInt>> {
8187
rho
8288
}
8389

90+
/// Perform the Fait Accompli test that check whether there are any more persistent pools to be selected.
8491
fn fa_test(s: &[Ratio<BigInt>], rho: &[Ratio<BigInt>], n: usize, i: usize) -> bool {
8592
let zero: Ratio<BigInt> = Ratio::from_integer(BigInt::zero());
8693
let one: Ratio<BigInt> = Ratio::from_integer(BigInt::one());

crypto-benchmarks.rs/src/key.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! High-level operations on Leios keys.
2+
13
use blst::min_sig::*;
24
use blst::BLST_ERROR;
35
use num_bigint::BigInt;
@@ -11,6 +13,7 @@ use crate::bls_vote;
1113
use crate::primitive::{arbitrary_poolkeyhash, KesSig, PoolKeyhash};
1214
use crate::util::{arbitrary_fixed_bytes, deserialize_fixed_bytes, serialize_fixed_bytes};
1315

16+
/// A secret key is a BLS scalar.
1417
#[derive(Clone, Debug)]
1518
pub struct SecKey(pub(crate) SecretKey);
1619

@@ -58,6 +61,7 @@ impl Arbitrary for SecKey {
5861
}
5962
}
6063

64+
/// A public key is a point in G2.
6165
#[derive(PartialEq, Eq, Clone, Debug)]
6266
pub struct PubKey(pub(crate) PublicKey);
6367

@@ -96,6 +100,7 @@ impl Arbitrary for PubKey {
96100
}
97101
}
98102

103+
/// A signature is a point in G1.
99104
#[derive(PartialEq, Eq, Clone, Debug)]
100105
pub struct Sig(pub(crate) Signature);
101106

@@ -136,6 +141,7 @@ impl Arbitrary for Sig {
136141
}
137142
}
138143

144+
/// A proof of possession is a pair of points in G1.
139145
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
140146
pub struct PoP {
141147
pub mu1: Sig, // 48 bytes
@@ -153,6 +159,7 @@ impl Arbitrary for PoP {
153159
}
154160
}
155161

162+
/// Key registration includes the pool hash, the public key, the proof of possession, and a KES signature.
156163
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
157164
pub struct Reg {
158165
pub pool: PoolKeyhash, // 28 bytes
@@ -161,6 +168,7 @@ pub struct Reg {
161168
pub kes_sig: KesSig, // 448 bytes
162169
} // 668 bytes
163170

171+
/// Generate an arbitrary pool registration.
164172
pub fn arbitrary_reg(g: &mut Gen, pool: &PoolKeyhash, sk: &SecKey) -> Reg {
165173
let (mu1, mu2) = bls_vote::make_pop(&sk.0);
166174
Reg {
@@ -182,6 +190,7 @@ impl Arbitrary for Reg {
182190
}
183191
}
184192

193+
/// Generate an arbitrary secret key along with its public key and proof of possession.
185194
pub fn key_gen() -> (SecKey, PubKey, PoP) {
186195
let sk: SecretKey = bls_vote::gen_key();
187196
let mvk: PublicKey = sk.sk_to_pk();
@@ -196,14 +205,17 @@ pub fn key_gen() -> (SecKey, PubKey, PoP) {
196205
)
197206
}
198207

208+
/// Verify a proof of possession `mu` for a public key `mvk`.
199209
pub fn check_pop(mvk: &PubKey, mu: &PoP) -> bool {
200210
bls_vote::check_pop(&mvk.0, &mu.mu1.0, &mu.mu2.0)
201211
}
202212

213+
/// Sign a message `msg` in the domain `dst` with the secret key `sk`.
203214
pub fn sign_message(sk: &SecKey, dst: &[u8], msg: &[u8]) -> Sig {
204215
Sig(sk.0.sign(msg, dst, &[]))
205216
}
206217

218+
/// Verify signature `sig` on a message `msg` in the domain `dst` using a public key `pk`.
207219
pub fn verify_message(pk: &PubKey, dst: &[u8], msg: &[u8], sig: &Sig) -> bool {
208220
let result = sig.0.verify(true, msg, dst, &[], &pk.0, true);
209221
result == BLST_ERROR::BLST_SUCCESS

0 commit comments

Comments
 (0)