1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use errors::Error;

/// List of types currently supported in the multihash spec.
///
/// Not all hash types are supported by this library.
#[derive(PartialEq, Eq, Clone, Debug, Copy, Hash)]
pub enum Hash {
    /// SHA-1 (20-byte hash size)
    SHA1,
    /// SHA-256 (32-byte hash size)
    SHA2256,
    /// SHA-512 (64-byte hash size)
    SHA2512,
    /// SHA3-512 (64-byte hash size)
    SHA3512,
    /// SHA3-384 (48-byte hash size)
    SHA3384,
    /// SHA3-256 (32-byte hash size)
    SHA3256,
    /// SHA3-224 (28-byte hash size)
    SHA3224,
    /// Keccak-224 (28-byte hash size)
    Keccak224,
    /// Keccak-256 (32-byte hash size)
    Keccak256,
    /// Keccak-384 (48-byte hash size)
    Keccak384,
    /// Keccak-512 (64-byte hash size)
    Keccak512,
    /// Encoding unsupported
    Blake2b,
    /// Encoding unsupported
    Blake2s,
}

impl Hash {
    /// Get the corresponding hash code
    pub fn code(&self) -> u8 {
        use Hash::*;

        match *self {
            SHA1 => 0x11,
            SHA2256 => 0x12,
            SHA2512 => 0x13,
            SHA3224 => 0x17,
            SHA3256 => 0x16,
            SHA3384 => 0x15,
            SHA3512 => 0x14,
            Keccak224 => 0x1A,
            Keccak256 => 0x1B,
            Keccak384 => 0x1C,
            Keccak512 => 0x1D,
            Blake2b => 0x40,
            Blake2s => 0x41,
        }
    }

    /// Get the hash length in bytes
    pub fn size(&self) -> u8 {
        use Hash::*;

        match *self {
            SHA1 => 20,
            SHA2256 => 32,
            SHA2512 => 64,
            SHA3224 => 28,
            SHA3256 => 32,
            SHA3384 => 48,
            SHA3512 => 64,
            Keccak224 => 28,
            Keccak256 => 32,
            Keccak384 => 48,
            Keccak512 => 64,
            Blake2b => 64,
            Blake2s => 32,

        }
    }

    /// Get the human readable name
    pub fn name(&self) -> &str {
        use Hash::*;

        match *self {
            SHA1 => "SHA1",
            SHA2256 => "SHA2-256",
            SHA2512 => "SHA2-512",
            SHA3512 => "SHA3-512",
            SHA3384 => "SHA3-384",
            SHA3256 => "SHA3-256",
            SHA3224 => "SHA3-224",
            Keccak224 => "Keccak-224",
            Keccak256 => "Keccak-256",
            Keccak384 => "Keccak-384",
            Keccak512 => "Keccak-512",
            Blake2b => "Blake-2b",
            Blake2s => "Blake-2s",
        }
    }

    pub fn from_code(code: u8) -> Result<Hash, Error> {
        use Hash::*;

        Ok(match code {
            0x11 => SHA1,
            0x12 => SHA2256,
            0x13 => SHA2512,
            0x14 => SHA3512,
            0x15 => SHA3384,
            0x16 => SHA3256,
            0x17 => SHA3224,
            0x1A => Keccak224,
            0x1B => Keccak256,
            0x1C => Keccak384,
            0x1D => Keccak512,
            0x40 => Blake2b,
            0x41 => Blake2s,
            _ => return Err(Error::UnknownCode),
        })
    }
}