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];