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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use eosio::{Checksum160, Checksum256, Checksum512};
use eosio_cdt_sys::{capi_checksum160, capi_checksum256, capi_checksum512};

/// Hashes `data` using RIPEMD160.
#[must_use]
#[inline]
pub fn ripemd160<T: AsRef<[u8]>>(data: T) -> Checksum160 {
    let data = data.as_ref();
    let data_ptr = data.as_ptr();
    #[allow(clippy::cast_possible_truncation)]
    let data_len = data.len() as u32;
    let mut c_hash = capi_checksum160::default();
    let c_hash_ptr: *mut capi_checksum160 =
        &mut c_hash as *mut _ as *mut capi_checksum160;
    unsafe { eosio_cdt_sys::ripemd160(data_ptr, data_len, c_hash_ptr) }
    c_hash.hash.into()
}

/// Tests if the RIPEMD160 hash generated from data matches the provided digest.
#[inline]
pub fn assert_ripemd160<C, T>(checksum: C, data: T)
where
    C: AsRef<Checksum160>,
    T: AsRef<[u8]>,
{
    let checksum = checksum.as_ref();
    let data = data.as_ref();
    let data_ptr = data.as_ptr();
    #[allow(clippy::cast_possible_truncation)]
    let data_len = data.len() as u32;
    let c_hash = capi_checksum160 {
        hash: checksum.to_bytes(),
        __bindgen_padding_0: [0_u32; 3],
    };
    let c_hash_ptr: *const capi_checksum160 =
        &c_hash as *const capi_checksum160;
    unsafe { eosio_cdt_sys::assert_ripemd160(data_ptr, data_len, c_hash_ptr) }
}

/// Hashes `data` using SHA1.
#[must_use]
#[inline]
pub fn sha1<T: AsRef<[u8]>>(data: T) -> Checksum160 {
    let data = data.as_ref();
    let data_ptr = data.as_ptr();
    #[allow(clippy::cast_possible_truncation)]
    let data_len = data.len() as u32;
    let mut c_hash = capi_checksum160::default();
    let c_hash_ptr: *mut capi_checksum160 =
        &mut c_hash as *mut _ as *mut capi_checksum160;
    unsafe { eosio_cdt_sys::sha1(data_ptr, data_len, c_hash_ptr) }
    c_hash.hash.into()
}

/// Tests if the SHA1 hash generated from data matches the provided digest.
#[inline]
pub fn assert_sha1<C, T>(checksum: C, data: T)
where
    C: AsRef<Checksum160>,
    T: AsRef<[u8]>,
{
    let checksum = checksum.as_ref();
    let data = data.as_ref();
    let data_ptr = data.as_ptr();
    #[allow(clippy::cast_possible_truncation)]
    let data_len = data.len() as u32;
    let c_hash = capi_checksum160 {
        hash: checksum.to_bytes(),
        __bindgen_padding_0: [0_u32; 3],
    };
    let c_hash_ptr: *const capi_checksum160 =
        &c_hash as *const capi_checksum160;
    unsafe { eosio_cdt_sys::assert_sha1(data_ptr, data_len, c_hash_ptr) }
}

/// Hashes `data` using SHA256.
#[must_use]
#[inline]
pub fn sha256<T: AsRef<[u8]>>(data: T) -> Checksum256 {
    let data = data.as_ref();
    let data_ptr = data.as_ptr();
    #[allow(clippy::cast_possible_truncation)]
    let data_len = data.len() as u32;
    let mut c_hash = capi_checksum256::default();
    let c_hash_ptr = &mut c_hash as *mut _ as *mut capi_checksum256;
    unsafe { eosio_cdt_sys::sha256(data_ptr, data_len, c_hash_ptr) }
    c_hash.hash.into()
}

/// Tests if the SHA256 hash generated from data matches the provided digest.
#[inline]
pub fn assert_sha256<C, T>(checksum: C, data: T)
where
    C: AsRef<Checksum256>,
    T: AsRef<[u8]>,
{
    let checksum = checksum.as_ref();
    let data = data.as_ref();
    let data_ptr = data.as_ptr();
    #[allow(clippy::cast_possible_truncation)]
    let data_len = data.len() as u32;
    let c_hash = capi_checksum256 {
        hash: checksum.to_bytes(),
    };
    let c_hash_ptr: *const capi_checksum256 =
        &c_hash as *const capi_checksum256;
    unsafe { eosio_cdt_sys::assert_sha256(data_ptr, data_len, c_hash_ptr) }
}

/// Hashes `data` using SHA512.
#[must_use]
#[inline]
pub fn sha512<T: AsRef<[u8]>>(data: T) -> Checksum512 {
    let data = data.as_ref();
    let data_ptr = data.as_ptr();
    #[allow(clippy::cast_possible_truncation)]
    let data_len = data.len() as u32;
    let mut c_hash = capi_checksum512::default();
    let c_hash_ptr: *mut capi_checksum512 =
        &mut c_hash as *mut _ as *mut capi_checksum512;
    unsafe { eosio_cdt_sys::sha512(data_ptr, data_len, c_hash_ptr) }
    c_hash.hash.into()
}

/// Tests if the SHA512 hash generated from data matches the provided digest.
#[inline]
pub fn assert_sha512<C, T>(checksum: C, data: T)
where
    C: AsRef<Checksum512>,
    T: AsRef<[u8]>,
{
    let checksum = checksum.as_ref();
    let data = data.as_ref();
    let data_ptr = data.as_ptr();
    #[allow(clippy::cast_possible_truncation)]
    let data_len = data.len() as u32;
    let c_hash = capi_checksum512 {
        hash: checksum.to_bytes(),
    };
    let c_hash_ptr: *const capi_checksum512 =
        &c_hash as *const capi_checksum512;
    unsafe { eosio_cdt_sys::assert_sha512(data_ptr, data_len, c_hash_ptr) }
}

// TODO recover_key
// TODO assert_recover_key