Skip to content

Commit

Permalink
feat: make GenesisMaterial available to wallets
Browse files Browse the repository at this point in the history
* add GenesisMaterial to hard-code genesis DBC inputs without
  randomness and make it available for use by wallets, etc.
* add genesis.rs for GenesisMaterial
* rename GenesisDbcShare::transaction_sig to mintnode_sig_share
* call GenesisMaterial::new() from MintNode::issue_genesis_dbc()
  • Loading branch information
dan-da committed Feb 23, 2022
1 parent 155be3e commit aad4e7f
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ pub mod mock {
// Make a list of (Index, SignatureShare) for combining sigs.
let node_sigs: Vec<(u64, &SignatureShare)> = genesis_set
.iter()
.map(|g| g.transaction_sig.threshold_crypto())
.map(|g| g.mintnode_sig_share.threshold_crypto())
.collect();

let mint_node_arbitrary = &mint_nodes[0];
Expand Down
90 changes: 90 additions & 0 deletions src/genesis.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use crate::{Amount, KeyImage, Owner, OwnerOnce, PublicKeyBlst, Result, SecretKeyBlst};
use blst_ringct::mlsag::{MlsagMaterial, TrueInput};
use blst_ringct::ringct::RingCtMaterial;
use blst_ringct::{Output, RevealedCommitment};
use blstrs::group::prime::PrimeCurveAffine;
use blstrs::group::Curve;
use blstrs::Scalar;
use blsttc::{poly::Poly, SecretKeySet};

/// represents all the inputs required to build the Genesis Dbc.
pub struct GenesisMaterial {
pub ringct_material: RingCtMaterial,
pub owner_once: OwnerOnce,
pub input_key_image: KeyImage,
}

impl GenesisMaterial {
/// This is the "real" amount that all network participants should use.
pub const STD_GENESIS_AMOUNT: Amount = 30000000;

/// generate the GenesisMaterial.
///
/// It is allowed to pass in an amount for local testing purposes.
/// However, to participate on a public network (mainnet, testnet)
/// one must use GenesisMaterial::STD_GENESIS_AMOUNT
///
/// todo: implement Network enum {Mainnet, Testnet, ...}
pub fn new(amount: Amount) -> Result<Self> {
// Make a secret key for the input to Genesis Tx.
let input_poly = Poly::zero();
let input_secret_key_set = SecretKeySet::from(input_poly);

// fixme, unwrap.
let input_secret_key =
SecretKeyBlst::from_bytes_be(&input_secret_key_set.secret_key().to_bytes()).unwrap();

// Make a secret key for the output of Genesis Tx. (The Genesis Dbc)
let poly = Poly::one();
let secret_key_set = SecretKeySet::from(poly);

let owner_once = OwnerOnce {
owner_base: Owner::from(secret_key_set.secret_key()),
derivation_index: [1; 32],
};

let secret_key_set_derived = secret_key_set.derive_child(&owner_once.derivation_index);

// create sk and derive pk.
let secret_key =
SecretKeyBlst::from_bytes_be(&secret_key_set_derived.secret_key().to_bytes()).unwrap();
let public_key = (PublicKeyBlst::generator() * secret_key).to_affine();

let true_input = TrueInput {
secret_key: input_secret_key,
revealed_commitment: RevealedCommitment {
value: amount,
blinding: 5.into(), // todo: choose Genesis blinding factor.
},
};

let input_key_image = true_input.key_image().to_affine().into();

// note: no decoy inputs because no other DBCs exist prior to genesis DBC.
let decoy_inputs = vec![];

let ring_len = decoy_inputs.len() + 1;
let r: Vec<(Scalar, Scalar)> = (0..ring_len)
.map(|_| (Scalar::default(), Scalar::default()))
.collect();

let mlsag_material = MlsagMaterial {
true_input,
decoy_inputs,
pi_base: 0,
alpha: (Default::default(), Default::default()),
r,
};

let ringct_material = RingCtMaterial {
inputs: vec![mlsag_material],
outputs: vec![Output { public_key, amount }],
};

Ok(Self {
ringct_material,
owner_once,
input_key_image,
})
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod builder;
mod dbc;
mod dbc_content;
mod error;
mod genesis;
mod key_manager;
mod mint;
mod owner;
Expand All @@ -32,6 +33,7 @@ pub use crate::{
dbc::Dbc,
dbc_content::{Amount, DbcContent},
error::{Error, Result},
genesis::GenesisMaterial,
key_manager::{
KeyManager, NodeSignature, PublicKey, PublicKeySet, Signature, SimpleKeyManager,
SimpleSigner,
Expand Down
66 changes: 15 additions & 51 deletions src/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,11 @@
// Outputs <= input value

use crate::{
Amount, AmountSecrets, DbcContent, Error, Hash, KeyImage, KeyManager, NodeSignature, Owner,
OwnerOnce, PublicKey, PublicKeySet, Result, SecretKeyBlst, SpentProof, SpentProofShare,
Amount, AmountSecrets, DbcContent, Error, GenesisMaterial, Hash, KeyImage, KeyManager,
NodeSignature, OwnerOnce, PublicKey, PublicKeySet, Result, SpentProof, SpentProofShare,
TransactionValidator,
};
use blst_ringct::mlsag::{MlsagMaterial, TrueInput};
use blst_ringct::ringct::{RingCtMaterial, RingCtTransaction};
use blst_ringct::{Output, RevealedCommitment};
use blstrs::group::Curve;
use blsttc::{poly::Poly, SecretKeySet};
use rand_core::RngCore;
use std::collections::{BTreeMap, BTreeSet};

Expand All @@ -40,7 +36,7 @@ pub struct GenesisDbcShare {
pub amount_secrets: AmountSecrets,
pub owner_once: OwnerOnce,
pub transaction: RingCtTransaction,
pub transaction_sig: NodeSignature,
pub mintnode_sig_share: NodeSignature,
pub input_key_image: KeyImage,
}

Expand Down Expand Up @@ -90,44 +86,11 @@ impl<K: KeyManager> MintNode<K> {
amount: Amount,
mut rng: impl RngCore + rand_core::CryptoRng,
) -> Result<(Self, GenesisDbcShare)> {
// note: for now, we bypass KeyManager and create the keys deterministically,
// as the same keys must be generated by all MintNodes.

// Make a secret key for the input to Genesis Tx.
let input_poly = Poly::zero();
let input_secret_key_set = SecretKeySet::from(input_poly);
let input_secret_key =
SecretKeyBlst::from_bytes_be(&input_secret_key_set.secret_key().to_bytes()).unwrap();

// Make a secret key for the output of Genesis Tx. (The Genesis Dbc)
let poly = Poly::one();
let secret_key_set = SecretKeySet::from(poly);
let owner_once =
OwnerOnce::from_owner_base(Owner::from(secret_key_set.secret_key()), &mut rng);
let secret_key_set_derived = secret_key_set.derive_child(&owner_once.derivation_index);

// create sk and derive pk.
let secret_key =
SecretKeyBlst::from_bytes_be(&secret_key_set_derived.secret_key().to_bytes()).unwrap();
let public_key = blst_ringct::public_key(secret_key).to_affine();

let true_input = TrueInput {
secret_key: input_secret_key,
revealed_commitment: RevealedCommitment {
value: amount,
blinding: 5.into(), // todo: choose Genesis blinding factor.
},
};

let input_key_image = true_input.key_image().to_affine().into();

// note: no decoy inputs because no other DBCs exist prior to genesis DBC.
let decoy_inputs = vec![];

let ringct_material = RingCtMaterial {
inputs: vec![MlsagMaterial::new(true_input, decoy_inputs, &mut rng)],
outputs: vec![Output { public_key, amount }],
};
let GenesisMaterial {
ringct_material,
owner_once,
input_key_image,
} = GenesisMaterial::new(amount)?;

// Here we sign as the input DBC owner.
let (transaction, revealed_commitments) = ringct_material.sign(&mut rng)?;
Expand All @@ -140,7 +103,7 @@ impl<K: KeyManager> MintNode<K> {
));

// Here we sign as the mint.
let transaction_sig = self
let mintnode_sig_share = self
.key_manager
.sign(&Hash::from(transaction.hash()))
.map_err(|e| Error::Signing(e.to_string()))?;
Expand All @@ -153,7 +116,7 @@ impl<K: KeyManager> MintNode<K> {
amount_secrets,
owner_once,
transaction,
transaction_sig,
mintnode_sig_share,
input_key_image,
},
))
Expand Down Expand Up @@ -248,8 +211,8 @@ impl<K: KeyManager> MintNode<K> {
#[cfg(test)]
mod tests {
use super::*;
use blst_ringct::DecoyInput;
use blsttc::SecretKey;
use blst_ringct::{DecoyInput, Output};
use blsttc::{SecretKey, SecretKeySet};
use quickcheck_macros::quickcheck;
use rand::SeedableRng;
use rand_core::SeedableRng as SeedableRngCore;
Expand All @@ -258,8 +221,9 @@ mod tests {

use crate::{
tests::{TinyInt, TinyVec},
AmountSecrets, Dbc, DbcBuilder, GenesisBuilderMock, OwnerOnce, ReissueRequestBuilder,
SimpleKeyManager, SimpleSigner, SpentBookNodeMock, SpentProofContent,
AmountSecrets, Dbc, DbcBuilder, GenesisBuilderMock, Owner, OwnerOnce,
ReissueRequestBuilder, SimpleKeyManager, SimpleSigner, SpentBookNodeMock,
SpentProofContent,
};

#[test]
Expand Down

0 comments on commit aad4e7f

Please sign in to comment.