pchain_types/
cryptography.rs

1/*
2    Copyright © 2023, ParallelChain Lab 
3    Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
4*/
5
6//! Cryptographic primitives like [keypairs](Keypair) and [SHA256](sha256) hashes.
7//! 
8//! ## Generating a Keypair 
9//! 
10//! ```
11//! // OsRng and ChaCha are good defaults for pseudorandom number generation.
12//! use rand::rngs::OsRng;
13//! use rand_chacha::{ChaCha20Rng, rand_core::SeedableRng};
14//! 
15//! let mut osrng = OsRng{};
16//! let mut chacha20_rng = ChaCha20Rng::from_rng(&mut osrng).unwrap();
17//! let keypair = Keypair::generate(&mut chacha20_rng);
18//! ```
19
20
21use sha2::{Sha256, Digest};
22use rs_merkle::{MerkleTree, algorithms};
23
24/// An Ed25519 keypair.
25pub type Keypair = ed25519_dalek::Keypair;
26
27/// An Ed25519 secret key.
28pub type SecretKey = ed25519_dalek::SecretKey;
29
30/// An Ed25519 public key.
31pub type PublicKey = ed25519_dalek::PublicKey;
32
33/// An Ed25519 signature.
34pub type Signature = ed25519_dalek::Signature;
35
36/// 64 bytes that *should be* an Ed25519 signature. 
37/// 
38/// Can be acquired from [Signature] using [Signature::to_bytes], and converted into it using `try_from`.
39pub type SignatureBytes = [u8; 64];
40
41/// Implemented by [Keypair] and [SecretKey] to [Signer::sign] arbitrary bytesequences.
42pub use ed25519_dalek::Signer;
43
44/// Implemented by [Keypair] and [PublicKey] to cryptographically [Verifier::verify] arbitrary bytesequences.
45pub use ed25519_dalek::Verifier;
46
47/// Either:
48/// - an Ed25519 public key representing an external account, or
49/// - a contract address.
50pub type PublicAddress = [u8; 32];
51
52pub fn contract_address(signer: &PublicAddress, nonce: u64) -> PublicAddress {
53    let mut hasher = Sha256::new();
54    let mut pre_image = Vec::new();
55    pre_image.extend(signer);
56    pre_image.extend(nonce.to_le_bytes().to_vec());
57
58    hasher.update(pre_image);
59
60    hasher.finalize().into()
61}
62
63/// A SHA256 hash over some message.
64pub type Sha256Hash = [u8; 32];
65
66/// Compute the SHA256 hash over some data.
67pub fn sha256<T: AsRef<[u8]>>(data: T) -> Sha256Hash {
68    let mut ret = Sha256::new();
69    ret.update(data);
70    ret.finalize().into()
71}
72
73/// Compute the Binary Merkle Tree root hash over a list of arbitrary data, e.g., [crate::blockchain::Transaction](transactions) or [crate::blockchain::Receipt](receipts).
74pub fn merkle_root<O: AsRef<[I]>, I: AsRef<[u8]>>(data: O) -> Sha256Hash {
75    // null hash really isn't all 0s. There is no hash value for a tree without root. But here 
76    // we use the 32-byte hash values to fill in the field definition inside data structures, for example, block header.
77    if data.as_ref().is_empty() {
78        return [0; 32]
79    }
80
81    let prehashed_leaves: Vec<[u8; 32]> = data
82        .as_ref()
83        .iter()
84        .map(sha256)
85        .collect();
86
87    let merkle_tree = MerkleTree::<algorithms::Sha256>::from_leaves(&prehashed_leaves);
88    merkle_tree.root().unwrap()
89}
90
91/// A 256-bit Bloom Filter.
92pub type BloomFilter = [u8; 256];