casper-node
casper-node copied to clipboard
Host function `generic_hash()` with blake2b/blake3 support.
In order to support Zero Knowledge software, cryptography related utils should be implemented as a host functions, otherwise execution cost would be too high. For example running Risc0 VM proof verification for simple sum of squares takes more than 6000 CSPR. The underlying hash used: sha256.
This PR adds host function called generic_hash(input, type)
with support for the following types:
-
HashAlgoType::Blake2b
- used existing blake2b implementation, -
HashAlgoType::Blake3b
- blake3 library was introduced.
We expect to add more algorithms, i.e. sha256, keccak, poseidon.
Example usage
Smart contract:
#![no_std]
#![no_main]
extern crate alloc;
use alloc::format;
use casper_contract::contract_api::{crypto, runtime};
use casper_types::HashAlgoType;
#[no_mangle]
pub extern "C" fn call() {
let input = "casper".as_bytes();
runtime::print(&format!("Input: {:?}", input));
let blake2b = crypto::generic_hash(input, HashAlgoType::Blake2b);
runtime::print(&format!("Blake2b hash: {:?}", blake2b));
let blake3 = crypto::generic_hash(input, HashAlgoType::Blake3);
runtime::print(&format!("Blake3 hash: {:?}", blake3));
}
Node output:
Input: [99, 97, 115, 112, 101, 114]
Blake2b hash: [163, 40, 63, 203, 149, 170, 125, 252, 231, 127, 90, 198, 44, 250, 234, 42, 1, 199, 20, 158, 150, 188, 25, 205, 21, 106, 255, 40, 204, 65, 45, 196]
Blake3 hash: [122, 158, 116, 51, 175, 213, 20, 50, 237, 63, 251, 230, 53, 2, 233, 86, 36, 159, 195, 109, 254, 108, 189, 210, 233, 1, 93, 219, 226, 1, 50, 217]
Considerations
~~1. AssemblyScript support~~
~~Is AssemblyScript binding required? I am pretty sure no one uses it.~~
Update: AssemblyScript is broken since a long time. I see no reason to include bindings for something that does not work.
~~2. Gas cost~~
~~For now, I used the same cost for generic_hash()
as defined for blake2()
- default fixed value 200. I can do benchmarks for WASM bytecode execution, but is there any conversion ratio between CPU time and execution cost?~~
Update: There will be new execution engine that will affect (lower) gas usage. It will be the better to make benchmarks then.
3. Place for core hashes implementation
Blake2b is implemented in types
package, which does not seem to be reasonable. I added blake3 to new module crypto
in execution engine, but I am open to discussing its location.
4. Single vs multiple host function
Do we want to introduce separate host functions for each hash algorithm?
5. Place for generic_hash()
in contract API
I was thinking of using runtime
, but finally decided to create new crypto
module.