Skip to content
Permalink
Browse files

Merge pull request #690 from input-output-hk/replace-fake-alg

Replace alg
  • Loading branch information...
NicolasDP committed May 16, 2019
2 parents c22ee2b + 4914204 commit fd01ad58176d668c583899a3275ca8d6303c957d
@@ -93,7 +93,10 @@ impl VerificationAlgorithm for Ed25519 {

fn signature_from_bytes(data: &[u8]) -> Result<Self::Signature, SignatureError> {
if data.len() != ed25519::SIGNATURE_LENGTH {
return Err(SignatureError::SizeInvalid);
return Err(SignatureError::SizeInvalid {
expected: ed25519::SIGNATURE_LENGTH,
got: data.len(),
});
}
let mut buf = [0; ed25519::SIGNATURE_LENGTH];
buf[0..ed25519::SIGNATURE_LENGTH].clone_from_slice(data);
@@ -62,7 +62,10 @@ impl SecretKeySizeStatic for Ed25519Bip32 {
impl From<i::SignatureError> for SignatureError {
fn from(v: i::SignatureError) -> Self {
match v {
i::SignatureError::InvalidLength(_) => SignatureError::SizeInvalid,
i::SignatureError::InvalidLength(got) => SignatureError::SizeInvalid {
expected: ed25519_bip32::SIGNATURE_SIZE,
got: got,
},
}
}
}
@@ -83,7 +83,10 @@ impl VerificationAlgorithm for Ed25519Extended {

fn signature_from_bytes(data: &[u8]) -> Result<Self::Signature, SignatureError> {
if data.len() != ed25519::SIGNATURE_LENGTH {
return Err(SignatureError::SizeInvalid);
return Err(SignatureError::SizeInvalid {
expected: ed25519::SIGNATURE_LENGTH,
got: data.len(),
});
}
let mut buf = [0; ed25519::SIGNATURE_LENGTH];
buf[0..ed25519::SIGNATURE_LENGTH].clone_from_slice(data);
@@ -80,7 +80,10 @@ impl VerificationAlgorithm for FakeMMM {

fn signature_from_bytes(data: &[u8]) -> Result<Self::Signature, SignatureError> {
if data.len() != ed25519::SIGNATURE_LENGTH {
return Err(SignatureError::SizeInvalid);
return Err(SignatureError::SizeInvalid {
expected: ed25519::SIGNATURE_LENGTH,
got: data.len(),
});
}
let mut buf = [0; ed25519::SIGNATURE_LENGTH];
buf[0..ed25519::SIGNATURE_LENGTH].clone_from_slice(data);
@@ -60,7 +60,10 @@ impl VerificationAlgorithm for SumEd25519_12 {

fn signature_from_bytes(data: &[u8]) -> Result<Self::Signature, SignatureError> {
sum::Signature::from_bytes(DEPTH, data).map_err(|e| match e {
sum::Error::InvalidSignatureSize(_) => SignatureError::SizeInvalid,
sum::Error::InvalidSignatureSize(_) => SignatureError::SizeInvalid {
expected: Self::SIGNATURE_SIZE,
got: data.len(),
},
_ => SignatureError::StructureInvalid,
})
}
@@ -465,7 +465,7 @@ impl Signature {
return Err(Error::InvalidSignatureSize(bytes.len()));
}
let found_depth = (bytes.len() - minimum_size) / 32;
if found_depth == depth.0 {
if found_depth != depth.0 {
return Err(Error::InvalidSignatureSize(bytes.len()));
}

@@ -720,6 +720,9 @@ mod tests {
if sk.is_updatable() {
update(&mut sk).unwrap();
}

let sigdata = sig.as_bytes();
assert_eq!(signature_size(depth), sigdata.len())
}
}

@@ -21,7 +21,7 @@ impl From<bool> for Verification {

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SignatureError {
SizeInvalid,
SizeInvalid { expected: usize, got: usize }, // expected, got in bytes
StructureInvalid,
}

@@ -59,7 +59,11 @@ impl<A: VerificationAlgorithm, T> fmt::Display for Signature<T, A> {
impl fmt::Display for SignatureError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SignatureError::SizeInvalid => write!(f, "Invalid Signature size"),
SignatureError::SizeInvalid { expected, got } => write!(
f,
"Invalid Signature size expecting {} got {}",
expected, got
),
SignatureError::StructureInvalid => write!(f, "Invalid Signature structure"),
}
}
@@ -23,25 +23,30 @@ The header is a small piece of data, containing enough informations for validati

Common (2 * 64 bits + 1 * 32 bits + 2 * 256 bits = 84 bytes):

* Size of Header: 16 bits: Maximum header is thus 64K not including the block content
* Version of block: 16 bits
* Size of Content: 32 bits
* Block Date: Epoch (32 bits) + Slot-id (32 bits)
* Chain length (number of ancestor blocks; first block has chain length 0): 32 bits
* Hash of content `H(Content)` (256 bits)
* Parent Header hash : 256 bits (with the special value of 0 to represent the lack of parent for the first block)
* Size of Header: 2 bytes (16 bits): Maximum header is thus 64K not including the block content
* Version of block: 2 bytes (16 bits)
* Size of Content: 4 bytes (32 bits)
* Block Date: Epoch (4 bytes, 32 bits) + Slot-id (4 bytes - 32 bits)
* Chain length (number of ancestor blocks; first block has chain length 0): 4 bytes (32 bits)
* Hash of content `H(Content)` (32 bytes - 256 bits)
* Parent Header hash : 32 bytes (256 bits)

We reserved the special value of all 0 for the parent header hash, to
represent the lack of parent for the block0, but for other blocks it's not
reserved and could represent, although with negligeable probability, a valid
block. In any case, it means that there's no special meaning to this value in
normal context.

In BFT the header also contains (768 bits = 96 bytes):

* BFT Public Key of the leader (256 bits)
* BFT Signature (512 bits)
* BFT Public Key of the leader (32 bytes)
* BFT Signature (64 bytes)

In Praos/Genesis the header also contains (128 bytes + between 480 to 1184 bytes = between 608 to 1312 bytes):
In Praos/Genesis the header also contains (616 bytes):

* VRF PubKey: 256 bits (curve25519-dalek)
* VRF Proof: 768 bits (curve25519-dalek DLEQs)
* KES Signature (content TBD)
* MMM+ed25519: Between 480 Bytes <=> 1184 Bytes
* VRF PubKey: 32 bytes (curve25519-dalek)
* VRF Proof: 96 bytes (curve25519-dalek DLEQs)
* KES Signature: 484 bytes (sumed25519-12)

Additionally, we introduce the capability to address each header individually
by using a cryptographic hash function : `H(HEADER)`. The hash include all
@@ -187,23 +192,23 @@ bytes.

The following parameter types exist:

| tag | name | value type | description |
|:-------|:-------|:------------|:--------------|
| 1 | discrimination | u8 | address discrimination; 1 for production, 2 for testing |
| 2 | block0-date | u64 | the official start time of the blockchain, in seconds since the Unix epoch |
| 3 | consensus| u16 | consensus version; 1 for BFT, 2 for Genesis Praos |
| 4 | slots-per-epoch | u32 | number of slots in an epoch |
| 5 | slot-duration | u8 | slot duration in seconds |
| 6 | epoch-stability-depth | u32 | the length of the suffix of the chain (in blocks) considered unstable |
| 8 | genesis-praos-param-f | Milli | determines maximum probability of a stakeholder being elected as leader in a slot |
| 9 | max-number-of-transactions-per-block | u32 | maximum number of transactions in a block |
| 10 | bft-slots-ratio | Milli | fraction of blocks to be created by BFT leaders |
| 11 | add-bft-leader | LeaderId | add a BFT leader |
| 12 | remove-bft-leader | LeaderId | remove a BFT leader |
| 13 | allow-account-creation | bool (u8) | 0 to enable account creation, 1 to disable |
| 14 | linear-fee | LinearFee | coefficients for fee calculations |
| 15 | proposal-expiration | u32 | number of epochs until an update proposal expires |
| 16 | kes-update-speed | u32 | maximum number of seconds per update for KES keys known by the system after start time |
| tag | name | value type | description |
| :--- | :----------------------------------- | :--------- | :------------------------------------------------------------------------------------- |
| 1 | discrimination | u8 | address discrimination; 1 for production, 2 for testing |
| 2 | block0-date | u64 | the official start time of the blockchain, in seconds since the Unix epoch |
| 3 | consensus | u16 | consensus version; 1 for BFT, 2 for Genesis Praos |
| 4 | slots-per-epoch | u32 | number of slots in an epoch |
| 5 | slot-duration | u8 | slot duration in seconds |
| 6 | epoch-stability-depth | u32 | the length of the suffix of the chain (in blocks) considered unstable |
| 8 | genesis-praos-param-f | Milli | determines maximum probability of a stakeholder being elected as leader in a slot |
| 9 | max-number-of-transactions-per-block | u32 | maximum number of transactions in a block |
| 10 | bft-slots-ratio | Milli | fraction of blocks to be created by BFT leaders |
| 11 | add-bft-leader | LeaderId | add a BFT leader |
| 12 | remove-bft-leader | LeaderId | remove a BFT leader |
| 13 | allow-account-creation | bool (u8) | 0 to enable account creation, 1 to disable |
| 14 | linear-fee | LinearFee | coefficients for fee calculations |
| 15 | proposal-expiration | u32 | number of epochs until an update proposal expires |
| 16 | kes-update-speed | u32 | maximum number of seconds per update for KES keys known by the system after start time |

`Milli` is a 64-bit entity that encoded a non-negative, fixed-point
number with a scaling factor of 1000. That is, the number 1.234 is
@@ -11,7 +11,7 @@ use crate::stake;
use crate::transaction::{AuthenticatedTransaction, NoExtra};
use chain_addr::Address;
use chain_crypto::{
Curve25519_2HashDH, Ed25519Extended, FakeMMM, SecretKey, VerifiableRandomFunction,
Curve25519_2HashDH, Ed25519Extended, SecretKey, SumEd25519_12, VerifiableRandomFunction,
};

pub struct BlockBuilder {
@@ -136,7 +136,7 @@ impl BlockBuilder {
pub fn make_genesis_praos_block(
mut self,
node_id: &stake::StakePoolId,
kes_signing_key: &mut SecretKey<FakeMMM>,
kes_signing_key: &mut SecretKey<SumEd25519_12>,
vrf_proof: <Curve25519_2HashDH as VerifiableRandomFunction>::VerifiedRandomOutput,
) -> Block {
assert_ne!(self.common.chain_length, ChainLength(0));
@@ -13,7 +13,7 @@ use chain_core::{
property,
};
use chain_crypto::{
self, Curve25519_2HashDH, Ed25519Extended, FakeMMM, Signature, VerifiableRandomFunction,
self, Curve25519_2HashDH, Ed25519Extended, Signature, SumEd25519_12, VerifiableRandomFunction,
};

pub type HeaderHash = Hash;
@@ -54,7 +54,7 @@ pub struct GenesisPraosProof {
}

#[derive(Debug, Clone)]
pub struct KESSignature(pub(crate) Signature<HeaderToSign, FakeMMM>);
pub struct KESSignature(pub(crate) Signature<HeaderToSign, SumEd25519_12>);

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Proof {
@@ -295,7 +295,8 @@ impl property::Header for Header {
mod test {
use super::*;
use crate::block::ConsensusVersion;
use chain_crypto::AsymmetricKey;
use chain_crypto::{AsymmetricKey, SecretKey, SumEd25519_12};
use lazy_static::lazy_static;
use num_traits::FromPrimitive;
use quickcheck::{Arbitrary, Gen, TestResult};

@@ -359,7 +360,11 @@ mod test {
};

let kes_proof = {
let mut sk = Arbitrary::arbitrary(g);
lazy_static! {
static ref SK_FIRST: SecretKey<SumEd25519_12> =
{ SecretKey::generate(&mut ChaChaRng::from_seed([0; 32])) };
}
let mut sk = SK_FIRST.clone(); // Arbitrary::arbitrary(g);
let signature = Signature::generate_update(&mut sk, &[0u8, 1, 2, 3]);
KESSignature(signature)
};
@@ -386,7 +386,8 @@ impl Readable for StakePoolRetirement {
mod test {
use super::*;
use crate::leadership::genesis::GenesisPraosLeader;
use chain_crypto::SecretKey;
use chain_crypto::{PublicKey, SecretKey, SumEd25519_12};
use lazy_static::lazy_static;
use quickcheck::{Arbitrary, Gen};

impl Arbitrary for Certificate {
@@ -444,13 +445,19 @@ mod test {
for byte in seed.iter_mut() {
*byte = Arbitrary::arbitrary(g);
}
lazy_static! {
static ref PK_KES: PublicKey<SumEd25519_12> = {
let sk = SecretKey::generate(&mut rand_chacha::ChaChaRng::from_seed([0; 32]));
sk.to_public()
};
}
let mut rng = rand_chacha::ChaChaRng::from_seed(seed);
StakePoolInfo {
serial: Arbitrary::arbitrary(g),
owners: vec![Arbitrary::arbitrary(g)],
initial_key: GenesisPraosLeader {
vrf_public_key: SecretKey::generate(&mut rng).to_public(),
kes_public_key: SecretKey::generate(&mut rng).to_public(),
kes_public_key: PK_KES.clone(),
},
}
}
@@ -30,9 +30,9 @@ fn chain_crypto_pub_err(e: crypto::PublicKeyError) -> ReadError {
}
fn chain_crypto_sig_err(e: crypto::SignatureError) -> ReadError {
match e {
crypto::SignatureError::SizeInvalid => {
ReadError::StructureInvalid("signature size invalid".to_string())
}
crypto::SignatureError::SizeInvalid { expected, got } => ReadError::StructureInvalid(
format!("signature size invalid, expected {} got {}", expected, got),
),
crypto::SignatureError::StructureInvalid => {
ReadError::StructureInvalid("signature structure invalid".to_string())
}
@@ -10,14 +10,14 @@ use crate::{
value::Value,
};
use chain_crypto::Verification as SigningVerification;
use chain_crypto::{Curve25519_2HashDH, FakeMMM, PublicKey, SecretKey};
use chain_crypto::{Curve25519_2HashDH, PublicKey, SecretKey, SumEd25519_12};
pub use vrfeval::{ActiveSlotsCoeff, ActiveSlotsCoeffError, Witness};
use vrfeval::{Nonce, PercentStake, VrfEvaluator};

/// Praos Leader consisting of the KES public key and VRF public key
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GenesisPraosLeader {
pub kes_public_key: PublicKey<FakeMMM>,
pub kes_public_key: PublicKey<SumEd25519_12>,
pub vrf_public_key: PublicKey<Curve25519_2HashDH>,
}

@@ -154,7 +154,7 @@ mod test {
use chain_core::property::Transaction as T;
use chain_core::property::{BlockId, HasTransaction};
use chain_crypto::{
algorithms::{Ed25519, Ed25519Extended, FakeMMM},
algorithms::{Ed25519, Ed25519Extended, SumEd25519_12},
SecretKey,
};
use quickcheck::{Arbitrary, StdGen};
@@ -4,7 +4,7 @@ use crate::{
ledger::Ledger,
stake::StakePoolId,
};
use chain_crypto::{Curve25519_2HashDH, Ed25519Extended, FakeMMM, SecretKey};
use chain_crypto::{Curve25519_2HashDH, Ed25519Extended, SecretKey, SumEd25519_12};
use chain_time::era::TimeEra;

pub mod bft;
@@ -50,7 +50,7 @@ pub struct BftLeader {

pub struct GenesisLeader {
pub node_id: StakePoolId,
pub sig_key: SecretKey<FakeMMM>,
pub sig_key: SecretKey<SumEd25519_12>,
pub vrf_key: SecretKey<Curve25519_2HashDH>,
}

0 comments on commit fd01ad5

Please sign in to comment.
You can’t perform that action at this time.