1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

//! ![Build Status](https://github.com/dusk-network/dusk--blindbid/workflows/Continuous%20integration/badge.svg)
//! [![Repository](https://img.shields.io/badge/github-dusk--blindbid-blueviolet?logo=github)](https://github.com/dusk-network/dusk-blindbid)
//! [![Documentation](https://img.shields.io/badge/docs-dusk--blindbid-blue?logo=rust)](https://docs.rs/dusk-blindbid/)
//!
//! # Contents
//!
//! This library provides the structures and the logic that the blind bid
//! protocol requires in order to work. Contains the most important structures:
//! `Bid` and `Score`.
//!
//! This means we can do things like:
//! ```rust
//! use dusk_blindbid::{Bid, Score, V_RAW_MIN, V_RAW_MAX};
//! use dusk_bls12_381::BlsScalar;
//! use dusk_pki::{PublicSpendKey, SecretSpendKey};
//! use dusk_jubjub::{JubJubScalar, JubJubAffine, GENERATOR_EXTENDED};
//! use phoenix_core::Message;
//! use rand::{Rng, thread_rng};
//!
//! // Generate a Bid from some fields we have.
//! let mut rng = rand::thread_rng();
//! let psk = PublicSpendKey::from(SecretSpendKey::new(
//!     JubJubScalar::one(),
//!     -JubJubScalar::one(),
//! ));
//! let secret_k = BlsScalar::one();
//! let secret = JubJubScalar::one();
//! let value: u64 =
//!     (&mut rand::thread_rng()).gen_range(V_RAW_MIN..V_RAW_MAX);
//! // Set the timestamps as the max values so the proofs do not fail
//! // for them (never expired or non-elegible).
//! let elegibility_ts = u64::MAX;
//! let expiration_ts = u64::MAX;
//!
//! let bid = Bid::new(
//!     Message::new(&mut rng, &secret, &psk, value),
//!     secret_k,
//!     psk.gen_stealth_address(&secret),
//!     elegibility_ts,
//!     expiration_ts,
//! );
//!
//! let poseidon_tree_root = BlsScalar::random(&mut thread_rng());
//!
//! // Generate fields for the Bid & required by the compute_score
//! let consensus_round_seed = BlsScalar::random(&mut thread_rng());
//! let latest_consensus_round = 50u64;
//! let latest_consensus_step = 50u64;
//!
//! // Generate a ProverID attached to the `Bid`.
//! let prover_id = bid.generate_prover_id(
//!     secret_k,
//!     BlsScalar::from(consensus_round_seed),
//!     BlsScalar::from(latest_consensus_round),
//!     BlsScalar::from(latest_consensus_step),
//! );
//!
//! // The next step is only doable if `std` feature is enabled.
//!
//! // Generate a `Score` for our Bid with the consensus parameters
//! #[cfg(feature = "std")]
//!  let score = Score::compute(
//!      &bid,
//!      &secret,
//!      &psk,
//!      secret_k,
//!      poseidon_tree_root,
//!      consensus_round_seed,
//!      latest_consensus_round,
//!      latest_consensus_step,
//!  ).expect("Score generation error");
//! ```
//!
//! # Rationale & Theory
//!
//! In order to participate in the SBA consensus, Block generators have to
//! submit a bid in DUSK. As long as their bid is active - and their full-node
//! is connected with the internet and running- they are participating in the
//! consensus rounds. Essentially, every time a consensus round is run, the
//! Block Generator software generates a comprehensive zero-knowledge proof, and
//! executes various steps in order to generate a valid candidate block, and
//! compete with the other Block Generators for a chance to become the winner of
//! the consensus round.
//!
//! ![](https://user-images.githubusercontent.com/1636833/107039506-468c9e80-67be-11eb-9fb1-7ba999b3d6dc.png)
//!
//! Below we describe the three main processes that happen
//! every consensus round. Please note that 1 and 2 are run as part of the same
//! algorithm.
//!
//! ## 1: Score generation.
//! Block Generators obtain a score from a lottery by executing the Score
//! Generation Function. The score is positively influenced by the amount of
//! DUSK that the Block Generator bids. In other words, the higher the bid, the
//! better the chance to generate a high score. This is important to guarantee
//! _Sybil attack_ protection.
//!
//! Without this link a bad actor could subvert the reputation system by
//! creating multiple identities. Also note: there are _minimum_ and _maximum_
//! thresholds that determine the minimum and maximum size of the bid.
//!
//! ## 2. Proof of Blind-Bid Generation.
//!
//! In general computing science, a circuit is a computational model through
//! which input values proceed through a sequence of gates, each of which
//! computes a specific function. In our case, the circuits perform the logical
//! checks with public and private inputs to make sure that the generated Blind
//! Bid proofs are generated by the rules of the game. For explanatory reasons,
//! we define two circuits although in practice, these two are a collection of
//! gadgets added up together in order to compose the BlindBidCircuit.
//!
//! For further information regarding the circuits, please check the
//! [blindbid-circuits crate](https://github.com/dusk-network/rusk/tree/master/circuits/blindbid)
//!
//! ## 3. Propagation.
//! During each consensus round, the Block Generator checks
//! the score that he produced, and verifies whether it is greater than the
//! _**minimum score threshold**_. If it is indeed greater, then the Block
//! Generator generates the aforementioned proofs and propagates the score
//! obtained, the zero-knowledge proof computed and various other elements
//! alongside the Block Candidate to his peers in the network.
//! The Block Generator that computed the highest score is considered to be the
//! leader of the current iteration of the consensus.
//!
//! # Documentation
//! The best usage example of this library can actually be found in the Bid
//! contract. This is the place where this lib provides all it's
//! functionallities together with PoseidonTrees and Zero Knowledge Proofs.
//! See: <https://github.com/dusk-network/rusk/tree/master/contracts/bid for more info and detail.>
//!
//! You can also check the documentation of this crate [here](https://docs.rs/dusk-blindbid/0.5.0/).
//!
//! # Licensing
//! This code is licensed under Mozilla Public License Version 2.0 (MPL-2.0).
//! Please see [LICENSE](https://github.com/dusk-network/dusk-blindbid/blob/master/LICENSE) for further info.
//!
//! # About
//! Protocol & Implementation designed by the [dusk](https://dusk.network) team.
//!
//! # Contributing
//! - If you want to contribute to this repository/project please, check [CONTRIBUTING.md](https://github.com/dusk-network/dusk-blindbid/blob/master/CONTRIBUTING.md)
//! - If you want to report a bug or request a new feature addition, please open
//!   an issue on this repository.

#![allow(non_snake_case)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc(
    html_logo_url = "https://lh3.googleusercontent.com/SmwswGxtgIANTbDrCOn5EKcRBnVdHjmYsHYxLq2HZNXWCQ9-fZyaea-bNgdX9eR0XGSqiMFi=w128-h128-e365",
    html_favicon_url = "https://dusk.network/lib/img/favicon-16x16.png",
    html_root_url = "https://docs.rs/dusk-blindbid/0.0.0"
)]

extern crate alloc;

pub(crate) mod bid;
pub(crate) mod errors;
pub use bid::{encoding::BID_HASHING_TYPE_FIELDS, Bid, Score};
pub use errors::BlindBidError;

/// The minimum amount of Dusk an user is permitted to bid.
pub const V_RAW_MIN: u64 = 50_000u64;
/// The maximum amount of Dusk an user is permitted to bid.
pub const V_RAW_MAX: u64 = 250_000u64;