Просмотр исходного кода

sdk/wif: Use sha2 crate and abstract double sha256 function.

parazyd 2 лет назад
Родитель
Сommit
336cbbd173
4 измененных файлов с 37 добавлено и 36 удалено
  1. 1 0
      Cargo.lock
  2. 1 1
      src/sdk/Cargo.toml
  3. 1 1
      src/sdk/src/crypto/mod.rs
  4. 34 34
      src/sdk/src/crypto/wif.rs

+ 1 - 0
Cargo.lock

@@ -1790,6 +1790,7 @@ dependencies = [
  "pasta_curves",
  "rand 0.8.5",
  "rand_core 0.6.4",
+ "sha2 0.10.8",
  "subtle",
  "thiserror",
 ]

+ 1 - 1
src/sdk/Cargo.toml

@@ -24,7 +24,7 @@ darkfi-serial = {path = "../serial", features = ["crypto"]}
 
 # Encoding
 bs58 = "0.5.0"
-sha256 = "1.4.0"
+sha2 = "0.10.8"
 
 # Cryptography
 blake2b_simd = "1.0.2"

+ 1 - 1
src/sdk/src/crypto/mod.rs

@@ -79,7 +79,7 @@ pub mod pasta_prelude {
 
 /// Wallet Import Format
 pub mod wif;
-pub use wif::WIF;
+pub use wif::Wif;
 
 #[macro_export]
 macro_rules! fp_from_bs58 {

+ 34 - 34
src/sdk/src/crypto/wif.rs

@@ -16,6 +16,11 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+use std::convert::TryInto;
+
+use pasta_curves::group::ff::PrimeField;
+use sha2::{Digest, Sha256};
+
 use crate::{
     crypto::{
         constants::{MAINNET_ADDRS_PREFIX, TESTNET_ADDRS_PREFIX},
@@ -23,27 +28,33 @@ use crate::{
     },
     error::ContractError,
 };
-use bs58;
-use pasta_curves::group::ff::PrimeField;
-use sha256;
-use std::convert::TryInto;
+
+fn double_sha256(input: &[u8]) -> [u8; 32] {
+    let mut hasher = Sha256::new();
+    hasher.update(input);
+    let first = hasher.finalize();
+
+    let mut hasher = Sha256::new();
+    hasher.update(first);
+    hasher.finalize().into()
+}
 
 #[derive(Clone, Debug)]
-pub struct WIF(String);
+pub struct Wif(String);
 
-/// wallet import format https://en.bitcoin.it/wiki/Wallet_import_format
-/// encodes pallas-curve base private key to base58 string.
-impl WIF {
+/// Wallet import format <https://en.bitcoin.it/wiki/Wallet_import_format>
+/// Encodes pallas-curve base field secret key to base58 string.
+impl Wif {
     /// Get inner wrapped object
     pub fn inner(&self) -> String {
         self.0.clone()
     }
 }
 
-/// convert `SecretKey` to wallet import format `WIF`
-impl From<SecretKey> for WIF {
+/// Convert `SecretKey` to wallet import format `Wif`
+impl From<&SecretKey> for Wif {
     /// Initialize WIF from `SecretKey`
-    fn from(secretkey: SecretKey) -> Self {
+    fn from(secretkey: &SecretKey) -> Self {
         // address to bytes
         let address: [u8; 32] = secretkey.inner().to_repr();
         // address prefix
@@ -58,23 +69,19 @@ impl From<SecretKey> for WIF {
         extended_addrs_prefix.copy_from_slice(&prefix);
         extended_addrs_main.copy_from_slice(&address);
         // extended address checksum
-        let checksum: [u8; 4] = {
-            let first_digest: String = sha256::digest_bytes(&extended_addrs);
-            let second_digest: &[u8] = &sha256::digest(first_digest).into_bytes();
-            [second_digest[0], second_digest[1], second_digest[2], second_digest[3]]
-        };
+        let checksum: [u8; 4] = double_sha256(&extended_addrs)[0..4].try_into().unwrap();
         let mut full_address: [u8; 37] = [0; 37];
         let (full_address_left, full_address_right) =
             full_address.split_at_mut(extended_addrs.len());
         full_address_left.copy_from_slice(&extended_addrs);
         full_address_right.copy_from_slice(&checksum);
-        WIF(bs58::encode(full_address).into_string())
+        Wif(bs58::encode(full_address).into_string())
     }
 }
 
 /// convert wallet import format `WIF` to `SecretKey`
-impl From<WIF> for SecretKey {
-    fn from(wif: WIF) -> Self {
+impl From<Wif> for SecretKey {
+    fn from(wif: Wif) -> Self {
         let full_address: Vec<u8> = bs58::decode(wif.0).into_vec().unwrap();
         // extract prefix
         // TODO set secret key type mainnet/testnet
@@ -88,13 +95,9 @@ impl From<WIF> for SecretKey {
         let wif_checksum: [u8; 4] =
             full_address[33..37].try_into().expect("slice with incorrect length");
         // validate checksum
-        let checksum: [u8; 4] = {
-            let first_digest: String = sha256::digest_bytes(&extended_addrs);
-            let second_digest: &[u8] = &sha256::digest(first_digest).into_bytes();
-            [second_digest[0], second_digest[1], second_digest[2], second_digest[3]]
-        };
+        let checksum: [u8; 4] = double_sha256(&extended_addrs)[0..4].try_into().unwrap();
         assert!(wif_checksum == checksum);
-        let sk: Result<SecretKey, ContractError> = SecretKey::from_bytes(addrs).into();
+        let sk: Result<SecretKey, ContractError> = SecretKey::from_bytes(addrs);
         sk.unwrap()
     }
 }
@@ -116,26 +119,23 @@ impl TryInto<SecretKey> for String {
         let wif_checksum: [u8; 4] =
             full_address[33..37].try_into().expect("slice with incorrect length");
         // validate checksum
-        let checksum: [u8; 4] = {
-            let first_digest: String = sha256::digest_bytes(&extended_addrs);
-            let second_digest: &[u8] = &sha256::digest(first_digest).into_bytes();
-            [second_digest[0], second_digest[1], second_digest[2], second_digest[3]]
-        };
+        let checksum: [u8; 4] = double_sha256(&extended_addrs)[0..4].try_into().unwrap();
         assert!(wif_checksum == checksum);
-        let sk: Result<SecretKey, ContractError> = SecretKey::from_bytes(addrs).into();
+        let sk: Result<SecretKey, ContractError> = SecretKey::from_bytes(addrs);
         Ok(sk.unwrap())
     }
 }
 
 #[cfg(test)]
 mod tests {
-    use crate::crypto::{wif::WIF, SecretKey};
+    use super::*;
+
     #[test]
     fn test_sk_towif() {
         let sk_bytes: [u8; 32] = [0; 32];
-        let sk_str = std::str::from_utf8(&sk_bytes).unwrap();
+        let _sk_str = std::str::from_utf8(&sk_bytes).unwrap();
         let sk = SecretKey::from_bytes(sk_bytes).unwrap();
-        let wif = WIF::from(sk);
+        let wif = Wif::from(&sk);
 
         let sk_res = match wif.try_into() {
             Err(why) => panic!("{:?}", why),