Files
icicle/wrappers/golang/core/sponge.go
ChickenLover 7fd9ed1b49 Feat/roman/tree builder (#525)
# Updates:

## Hashing

 - Added SpongeHasher class
 - Can be used to accept any hash function as an argument
 - Absorb and squeeze are now separated
- Memory management is now mostly done by SpongeHasher class, each hash
function only describes permutation kernels

## Tree builder

 - Tree builder is now hash-agnostic. 
 - Tree builder now supports 2D input (matrices)
- Tree builder can now use two different hash functions for layer 0 and
compression layers

## Poseidon1

 - Interface changed to classes
 - Now allows for any alpha
 - Now allows passing constants not in a single vector
 - Now allows for any domain tag
 - Constants are now released upon going out of scope
 - Rust wrappers changed to Poseidon struct
 
 ## Poseidon2
 
 - Interface changed to classes
 - Constants are now released upon going out of scope
 - Rust wrappers changed to Poseidon2 struct
 
## Keccak

 - Added Keccak class which inherits SpongeHasher
 - Now doesn't use gpu registers for storing states
 
 To do:
- [x] Update poseidon1 golang bindings
- [x] Update poseidon1 examples
- [x] Fix poseidon2 cuda test
- [x] Fix poseidon2 merkle tree builder test
- [x] Update keccak class with new design
- [x] Update keccak test
- [x] Check keccak correctness
- [x] Update tree builder rust wrappers
- [x] Leave doc comments

Future work:  
- [ ] Add keccak merkle tree builder externs
- [ ] Add keccak rust tree builder wrappers
- [ ] Write docs
- [ ] Add example
- [ ] Fix device output for tree builder

---------

Co-authored-by: Jeremy Felder <jeremy.felder1@gmail.com>
Co-authored-by: nonam3e <71525212+nonam3e@users.noreply.github.com>
2024-07-11 13:46:25 +07:00

106 lines
2.7 KiB
Go

package core
import (
"fmt"
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
)
type SpongeConfig struct {
/// Details related to the device such as its id and stream.
Ctx cr.DeviceContext
areInputsOnDevice bool
areResultsOnDevice bool
InputRate uint32
OutputRate uint32
Offset uint32
/// If true - input should be already aligned for poseidon permutation.
/// Aligned format: [0, A, B, 0, C, D, ...] (as you might get by using loop_state)
/// not aligned format: [A, B, 0, C, D, 0, ...] (as you might get from cudaMemcpy2D)
RecursiveSqueeze bool
/// If true, hash results will also be copied in the input pointer in aligned format
Aligned bool
/// Whether to run the SpongeHash asynchronously. If set to `true`, the SpongeHash function will be non-blocking
/// and you'd need to synchronize it explicitly by running `cudaStreamSynchronize` or `cudaDeviceSynchronize`.
/// If set to `false`, the SpongeHash function will block the current CPU thread.
IsAsync bool
}
func GetDefaultSpongeConfig() SpongeConfig {
ctx, _ := cr.GetDefaultDeviceContext()
return SpongeConfig{
ctx,
false,
false,
0,
0,
0,
false,
false,
false,
}
}
func SpongeInputCheck(inputs HostOrDeviceSlice, numberOfStates, inputBlockLength, inputRate uint32, ctx *cr.DeviceContext) {
if inputBlockLength > inputRate {
errorString := fmt.Sprintf(
"Input block (%d) can't be greater than input rate (%d)",
inputBlockLength,
inputRate,
)
panic(errorString)
}
inputsSizeExpected := inputBlockLength * numberOfStates
if inputs.Len() < int(inputsSizeExpected) {
errorString := fmt.Sprintf(
"inputs len is %d; but needs to be at least %d",
inputs.Len(),
inputsSizeExpected,
)
panic(errorString)
}
if inputs.IsOnDevice() {
inputs.(DeviceSlice).CheckDevice()
}
}
func SpongeStatesCheck(states DeviceSlice, numberOfStates, width uint32, ctx *cr.DeviceContext) {
statesSizeExpected := width * numberOfStates
if states.Len() < int(statesSizeExpected) {
errorString := fmt.Sprintf(
"inputs len is %d; but needs to be at least %d",
states.Len(),
statesSizeExpected,
)
panic(errorString)
}
states.CheckDevice()
}
func SpongeOutputsCheck(outputs HostOrDeviceSlice, numberOfStates, outputLen, width uint32, recursive bool, ctx *cr.DeviceContext) {
var outputsSizeExpected uint32
if recursive {
outputsSizeExpected = width * numberOfStates
} else {
outputsSizeExpected = outputLen * numberOfStates
}
if outputs.Len() < int(outputsSizeExpected) {
errorString := fmt.Sprintf(
"outputs len is %d; but needs to be at least %d",
outputs.Len(),
outputsSizeExpected,
)
panic(errorString)
}
if outputs.IsOnDevice() {
outputs.(DeviceSlice).CheckDevice()
}
}