casper_contract/contract_api/
cryptography.rs

1//! Functions with cryptographic utils.
2
3use casper_types::{
4    api_error,
5    bytesrepr::{FromBytes, ToBytes, U8_SERIALIZED_LENGTH},
6    ApiError, HashAlgorithm, PublicKey, Signature, BLAKE2B_DIGEST_LENGTH,
7};
8
9use crate::{ext_ffi, unwrap_or_revert::UnwrapOrRevert};
10
11/// Computes digest hash, using provided algorithm type.
12pub fn generic_hash<T: AsRef<[u8]>>(input: T, algo: HashAlgorithm) -> [u8; 32] {
13    let mut ret = [0; 32];
14
15    let result = unsafe {
16        ext_ffi::casper_generic_hash(
17            input.as_ref().as_ptr(),
18            input.as_ref().len(),
19            algo as u8,
20            ret.as_mut_ptr(),
21            BLAKE2B_DIGEST_LENGTH,
22        )
23    };
24    api_error::result_from(result).unwrap_or_revert();
25    ret
26}
27
28/// Attempts to recover a Secp256k1 [`PublicKey`] from a message and a signature over it.
29pub fn recover_secp256k1<T: AsRef<[u8]>>(
30    data: T,
31    signature: &Signature,
32    recovery_id: u8,
33) -> Result<PublicKey, ApiError> {
34    let mut buffer = [0; U8_SERIALIZED_LENGTH + PublicKey::SECP256K1_LENGTH];
35    let signature_bytes = signature.to_bytes().unwrap_or_revert();
36
37    let result = unsafe {
38        ext_ffi::casper_recover_secp256k1(
39            data.as_ref().as_ptr(),
40            data.as_ref().len(),
41            signature_bytes.as_ptr(),
42            signature_bytes.len(),
43            buffer.as_mut_ptr(),
44            recovery_id,
45        )
46    };
47
48    PublicKey::from_bytes(&buffer)
49        .map(|(key, _)| key)
50        .map_err(|_| ApiError::from(result as u32))
51}
52
53/// Verifies the signature of the given message against the given public key.
54pub fn verify_signature<T: AsRef<[u8]>>(
55    data: T,
56    signature: &Signature,
57    public_key: &PublicKey,
58) -> Result<(), ApiError> {
59    let signature_bytes = signature.to_bytes().unwrap_or_revert();
60    let public_key_bytes = public_key.to_bytes().unwrap_or_revert();
61
62    let result = unsafe {
63        ext_ffi::casper_verify_signature(
64            data.as_ref().as_ptr(),
65            data.as_ref().len(),
66            signature_bytes.as_ptr(),
67            signature_bytes.len(),
68            public_key_bytes.as_ptr(),
69            public_key_bytes.len(),
70        )
71    };
72
73    api_error::result_from(result)
74}