Skip to content

Commit

Permalink
keccak docs (#508)
Browse files Browse the repository at this point in the history
This PR adds keccak docs

---------

Co-authored-by: Leon Hibnik <107353745+LeonHibnik@users.noreply.github.com>
  • Loading branch information
nonam3e and LeonHibnik authored May 8, 2024
1 parent 2905d2a commit c30e333
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 5 deletions.
94 changes: 94 additions & 0 deletions docs/docs/icicle/golang-bindings/keccak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Keccak

## Keccak Example

```go
package main

import (
"encoding/hex"

"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
"github.com/ingonyama-zk/icicle/v2/wrappers/golang/hash/keccak"
)

func createHostSliceFromHexString(hexString string) core.HostSlice[uint8] {
byteArray, err := hex.DecodeString(hexString)
if err != nil {
panic("Not a hex string")
}
return core.HostSliceFromElements([]uint8(byteArray))
}

func main() {
input := createHostSliceFromHexString("1725b6")
outHost256 := make(core.HostSlice[uint8], 32)

cfg := keccak.GetDefaultKeccakConfig()
e := keccak.Keccak256(input, int32(input.Len()), 1, outHost256, &cfg)
if e.CudaErrorCode != cr.CudaSuccess {
panic("Keccak256 hashing failed")
}

outHost512 := make(core.HostSlice[uint8], 64)
e = keccak.Keccak512(input, int32(input.Len()), 1, outHost512, &cfg)
if e.CudaErrorCode != cr.CudaSuccess {
panic("Keccak512 hashing failed")
}

numberOfBlocks := 3
outHostBatch256 := make(core.HostSlice[uint8], 32*numberOfBlocks)
e = keccak.Keccak256(input, int32(input.Len()/numberOfBlocks), int32(numberOfBlocks), outHostBatch256, &cfg)
if e.CudaErrorCode != cr.CudaSuccess {
panic("Keccak256 batch hashing failed")
}
}
```

## Keccak Methods

```go
func Keccak256(input core.HostOrDeviceSlice, inputBlockSize, numberOfBlocks int32, output core.HostOrDeviceSlice, config *KeccakConfig) core.IcicleError
func Keccak512(input core.HostOrDeviceSlice, inputBlockSize, numberOfBlocks int32, output core.HostOrDeviceSlice, config *KeccakConfig) core.IcicleError
```

### Parameters

- **`input`**: A slice containing the input data for the Keccak256 hash function. It can reside in either host memory or device memory.
- **`inputBlockSize`**: An integer specifying the size of the input data for a single hash.
- **`numberOfBlocks`**: An integer specifying the number of results in the hash batch.
- **`output`**: A slice where the resulting hash will be stored. This slice can be in host or device memory.
- **`config`**: A pointer to a `KeccakConfig` object, which contains various configuration options for the Keccak256 operation.

### Return Value

- **`CudaError`**: Returns a CUDA error code indicating the success or failure of the Keccak256/Keccak512 operation.

## KeccakConfig

The `KeccakConfig` structure holds configuration parameters for the Keccak256/Keccak512 operation, allowing customization of its behavior to optimize performance based on the specifics of the operation or the underlying hardware.

```go
type KeccakConfig struct {
Ctx cr.DeviceContext
areInputsOnDevice bool
areOutputsOnDevice bool
IsAsync bool
}
```

### Fields

- **`Ctx`**: Device context containing details like device id and stream.
- **`areInputsOnDevice`**: Indicates if input data is located on the device.
- **`areOutputsOnDevice`**: Indicates if output hash is stored on the device.
- **`IsAsync`**: If true, runs the Keccak256/Keccak512 operation asynchronously.

### Default Configuration

Use `GetDefaultKeccakConfig` to obtain a default configuration, which can then be customized as needed.

```go
func GetDefaultKeccakConfig() KeccakConfig
```
22 changes: 22 additions & 0 deletions docs/docs/icicle/primitives/keccak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Keccak

[Keccak](https://keccak.team/files/Keccak-implementation-3.2.pdf) is a cryptographic hash function designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche. It was selected as the winner of the NIST hash function competition, becoming the basis for the [SHA-3 standard](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf).

Keccak operates on a message input of any length and produces a fixed-size hash output. The hash function is built upon the sponge construction, which involves absorbing the input data followed by squeezing out the hash value.

At its core, Keccak consists of a permutation function operating on a state array. The permutation function employs a round function that operates iteratively on the state array. Each round consists of five main steps:

- **Theta:** This step introduces diffusion by performing a bitwise XOR operation between the state and a linear combination of its neighboring columns.
- **Rho:** This step performs bit rotation operations on each lane of the state array.
- **Pi:** This step rearranges the positions of the lanes in the state array.
- **Chi:** This step applies a nonlinear mixing operation to each lane of the state array.
- **Iota:** This step introduces a round constant to the state array.

## Using Keccak

ICICLE Keccak supports batch hashing, which can be utilized for constructing a merkle tree.

### Supported Bindings

- [Golang](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang/hash/keccak)
- [Rust](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/rust/icicle-hash)
1 change: 1 addition & 0 deletions docs/docs/icicle/primitives/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ This section of the documentation is dedicated to the ICICLE primitives, we will

- [MSM](./msm.md)
- [NTT](./ntt.md)
- [Keccak Hash](./keccak.md)
- [Poseidon Hash](./poseidon.md)
96 changes: 96 additions & 0 deletions docs/docs/icicle/rust-bindings/keccak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Keccak

## Keccak Example

```rust
use icicle_cuda_runtime::memory::{DeviceVec, HostSlice};
use icicle_hash::keccak::{keccak256, KeccakConfig};
use rand::{self, Rng};

fn main() {
let mut rng = rand::thread_rng();
let initial_data: Vec<u8> = (0..120).map(|_| rng.gen::<u8>()).collect();
println!("initial data: {}", hex::encode(&initial_data));
let input = HostSlice::<u8>::from_slice(initial_data.as_slice());
let mut output = DeviceVec::<u8>::cuda_malloc(32).unwrap();

let mut config = KeccakConfig::default();
keccak256(input, initial_data.len() as i32, 1, &mut output[..], &mut config).expect("Failed to execute keccak256 hashing");

let mut output_host = vec![0_u8; 32];
output.copy_to_host(HostSlice::from_mut_slice(&mut output_host[..])).unwrap();

println!("keccak256 result: {}", hex::encode(&output_host));
}
```

## Keccak Methods

```rust
pub fn keccak256(
input: &(impl HostOrDeviceSlice<u8> + ?Sized),
input_block_size: i32,
number_of_blocks: i32,
output: &mut (impl HostOrDeviceSlice<u8> + ?Sized),
config: &mut KeccakConfig,
) -> IcicleResult<()>

pub fn keccak512(
input: &(impl HostOrDeviceSlice<u8> + ?Sized),
input_block_size: i32,
number_of_blocks: i32,
output: &mut (impl HostOrDeviceSlice<u8> + ?Sized),
config: &mut KeccakConfig,
) -> IcicleResult<()>
```

### Parameters

- **`input`**: A slice containing the input data for the Keccak256 hash function. It can reside in either host memory or device memory.
- **`input_block_size`**: An integer specifying the size of the input data for a single hash.
- **`number_of_blocks`**: An integer specifying the number of results in the hash batch.
- **`output`**: A slice where the resulting hash will be stored. This slice can be in host or device memory.
- **`config`**: A pointer to a `KeccakConfig` object, which contains various configuration options for the Keccak256 operation.

### Return Value

- **`IcicleResult`**: Returns a CUDA error code indicating the success or failure of the Keccak256/Keccak512 operation.

## KeccakConfig

The `KeccakConfig` structure holds configuration parameters for the Keccak256/Keccak512 operation, allowing customization of its behavior to optimize performance based on the specifics of the operation or the underlying hardware.

```rust
pub struct KeccakConfig<'a> {
pub ctx: DeviceContext<'a>,
pub are_inputs_on_device: bool,
pub are_outputs_on_device: bool,
pub is_async: bool,
}
```

### Fields

- **`ctx`**: Device context containing details like device id and stream.
- **`are_inputs_on_device`**: Indicates if input data is located on the device.
- **`are_outputs_on_device`**: Indicates if output hash is stored on the device.
- **`is_async`**: If true, runs the Keccak256/Keccak512 operation asynchronously.

### Usage

Example initialization with default settings:

```rust
let default_config = KeccakConfig::default();
```

Customizing the configuration:

```rust
let custom_config = NTTConfig {
ctx: custom_device_context,
are_inputs_on_device: true,
are_outputs_on_device: true,
is_async: false,
};
```
15 changes: 15 additions & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ module.exports = {
label: "NTT",
id: "icicle/primitives/ntt",
},
{
type: "doc",
label: "Keccak Hash",
id: "icicle/primitives/keccak",
},
{
type: "doc",
label: "Poseidon Hash",
Expand Down Expand Up @@ -100,6 +105,11 @@ module.exports = {
label: "Vector operations",
id: "icicle/golang-bindings/vec-ops",
},
{
type: "doc",
label: "Keccak Hash",
id: "icicle/golang-bindings/keccak",
},
{
type: "doc",
label: "Multi GPU Support",
Expand Down Expand Up @@ -147,6 +157,11 @@ module.exports = {
label: "Vector operations",
id: "icicle/rust-bindings/vec-ops",
},
{
type: "doc",
label: "Keccak Hash",
id: "icicle/rust-bindings/keccak",
},
{
type: "doc",
label: "Multi GPU Support",
Expand Down
14 changes: 9 additions & 5 deletions wrappers/rust/icicle-hash/src/keccak/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ pub struct KeccakConfig<'a> {
pub ctx: DeviceContext<'a>,

/// True if inputs are on device and false if they're on host. Default value: false.
are_inputs_on_device: bool,
pub are_inputs_on_device: bool,

/// If true, output is preserved on device, otherwise on host. Default value: false.
are_outputs_on_device: bool,
pub are_outputs_on_device: bool,

/// Whether to run the Keccak asynchronously. If set to `true`, the keccak_hash function will be
/// non-blocking and you'd need to synchronize it explicitly by running
/// `cudaStreamSynchronize` or `cudaDeviceSynchronize`. If set to false, keccak_hash
/// function will block the current CPU thread.
is_async: bool,
pub is_async: bool,
}

impl<'a> Default for KeccakConfig<'a> {
Expand Down Expand Up @@ -68,8 +68,10 @@ pub fn keccak256(
input_block_size: i32,
number_of_blocks: i32,
output: &mut (impl HostOrDeviceSlice<u8> + ?Sized),
config: &KeccakConfig,
config: &mut KeccakConfig,
) -> IcicleResult<()> {
config.are_inputs_on_device = input.is_on_device();
config.are_outputs_on_device = output.is_on_device();
unsafe {
keccak256_cuda(
input.as_ptr(),
Expand All @@ -87,8 +89,10 @@ pub fn keccak512(
input_block_size: i32,
number_of_blocks: i32,
output: &mut (impl HostOrDeviceSlice<u8> + ?Sized),
config: &KeccakConfig,
config: &mut KeccakConfig,
) -> IcicleResult<()> {
config.are_inputs_on_device = input.is_on_device();
config.are_outputs_on_device = output.is_on_device();
unsafe {
keccak512_cuda(
input.as_ptr(),
Expand Down

0 comments on commit c30e333

Please sign in to comment.