Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Blake2s hints (Part 4) #315

Merged
merged 36 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ce47497
Begin implemneting blake2s
fmoletta Oct 2, 2023
bc5f5d4
Finish blake2s impl
fmoletta Oct 3, 2023
756aec9
Add unit test
fmoletta Oct 3, 2023
4e89d38
Add more unit tests
fmoletta Oct 3, 2023
3073bda
Add integration test
fmoletta Oct 3, 2023
d9564ff
Implement BLAKE2S_COMPUTE
fmoletta Oct 3, 2023
5039f58
Add unit tests
fmoletta Oct 3, 2023
e32a854
Add unit tests
fmoletta Oct 3, 2023
628dbcd
Add newline
fmoletta Oct 3, 2023
e3ae43d
Add integration test
fmoletta Oct 3, 2023
a87d704
Implement BLAKE2S_ADD_UINT256_BIGEND hint
fmoletta Oct 3, 2023
d7004d9
Add unit test
fmoletta Oct 3, 2023
c55aefd
Add integration test
fmoletta Oct 3, 2023
6b90c98
Implement finalize_blake2s hint
fmoletta Oct 3, 2023
2e6a7e0
Fix removed line
fmoletta Oct 3, 2023
3d44715
Add unit test
fmoletta Oct 3, 2023
101dc93
Fix test values
fmoletta Oct 3, 2023
909ac06
Add + expand integration test
fmoletta Oct 3, 2023
c1ef6b0
Implement hint + add quickfix to makefile
fmoletta Oct 3, 2023
16982bc
Add hint + integration test
fmoletta Oct 3, 2023
e94855c
Implement finalize v3
fmoletta Oct 3, 2023
c3c77e9
Add integration test
fmoletta Oct 3, 2023
0346fd5
Implement sha256 input hint
fmoletta Oct 3, 2023
76bc3e5
Add unit tests
fmoletta Oct 3, 2023
fa33713
Add exmaple blake compress hint
fmoletta Oct 4, 2023
8bcee03
Add unit test
fmoletta Oct 4, 2023
af1f729
Clone from main branch
fmoletta Oct 5, 2023
a22582c
Merge branch 'blake2s-hints-3' into blake2s-hints-4
fmoletta Oct 5, 2023
206a70b
Update cairo version
fmoletta Oct 26, 2023
a7b19b7
Merge branch 'main' of github.com:lambdaclass/cairo-vm.go into blake2…
fmoletta Oct 26, 2023
f692710
fix conflict
fmoletta Oct 26, 2023
85a60e9
fix conflict
fmoletta Oct 26, 2023
f04da44
Merge branch 'blake2s-hints-3' into blake2s-hints-4
fmoletta Oct 26, 2023
f00d78e
Update cairo-vm version
fmoletta Nov 21, 2023
6bec3e0
Merge branch 'blake2s-hints-3' into blake2s-hints-4
fmoletta Nov 21, 2023
4d675a2
Merge branch 'main' into blake2s-hints-4
pefontana Nov 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
654 changes: 654 additions & 0 deletions cairo_programs/example_blake2s.cairo

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions cairo_programs/finalize_blake2s_v2.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
%builtins range_check bitwise

from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.cairo_blake2s.blake2s import blake2s, _finalize_blake2s_inner, _get_sigma, INSTANCE_SIZE, INPUT_BLOCK_FELTS
from starkware.cairo.common.cairo_blake2s.packed_blake2s import N_PACKED_INSTANCES, blake2s_compress
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.registers import get_fp_and_pc
from starkware.cairo.common.math import assert_nn_le, split_felt, unsigned_div_rem

const BLAKE2S_INPUT_CHUNK_SIZE_FELTS = INPUT_BLOCK_FELTS;

// Verifies that the results of blake2s() are valid.
func finalize_blake2s{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}(
blake2s_ptr_start: felt*, blake2s_ptr_end: felt*
) {
alloc_locals;

let (__fp__, _) = get_fp_and_pc();

let (sigma) = _get_sigma();

tempvar n = (blake2s_ptr_end - blake2s_ptr_start) / INSTANCE_SIZE;
if (n == 0) {
return ();
}

%{
# Add dummy pairs of input and output.
from starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress

_n_packed_instances = int(ids.N_PACKED_INSTANCES)
assert 0 <= _n_packed_instances < 20
_blake2s_input_chunk_size_felts = int(ids.BLAKE2S_INPUT_CHUNK_SIZE_FELTS)
assert 0 <= _blake2s_input_chunk_size_felts < 100

message = [0] * _blake2s_input_chunk_size_felts
modified_iv = [IV[0] ^ 0x01010020] + IV[1:]
output = blake2s_compress(
message=message,
h=modified_iv,
t0=0,
t1=0,
f0=0xffffffff,
f1=0,
)
padding = (modified_iv + message + [0, 0xffffffff] + output) * (_n_packed_instances - 1)
segments.write_arg(ids.blake2s_ptr_end, padding)
%}

// Compute the amount of chunks (rounded up).
let (local n_chunks, _) = unsigned_div_rem(n + N_PACKED_INSTANCES - 1, N_PACKED_INSTANCES);
let blake2s_ptr = blake2s_ptr_start;
_finalize_blake2s_inner{blake2s_ptr=blake2s_ptr}(n=n_chunks, sigma=sigma);
return ();
}

func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() {
alloc_locals;
let inputs: felt* = alloc();
assert inputs[0] = 'Hell';
assert inputs[1] = 'o Wo';
assert inputs[2] = 'rld';
let (local blake2s_ptr_start) = alloc();
let blake2s_ptr = blake2s_ptr_start;
let (output) = blake2s{range_check_ptr=range_check_ptr, blake2s_ptr=blake2s_ptr}(inputs, 9);
finalize_blake2s(blake2s_ptr_start, blake2s_ptr);
return ();
}
54 changes: 54 additions & 0 deletions pkg/hints/blake2s_hints.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,57 @@ func blake2sFinalize(ids IdsManager, vm *VirtualMachine) error {
_, err = vm.Segments.LoadData(blake2sPtrEnd, &data)
return err
}

func blake2sFinalizeV3(ids IdsManager, vm *VirtualMachine) error {
const N_PACKED_INSTANCES = 7
blake2sPtrEnd, err := ids.GetRelocatable("blake2s_ptr_end", vm)
if err != nil {
return err
}
var message [16]uint32
modifiedIv := IV()
modifiedIv[0] = modifiedIv[0] ^ 0x01010020
output := Blake2sCompress(modifiedIv, message, 0, 0, 0xffffffff, 0)
padding := message[:]
padding = append(padding, modifiedIv[:]...)
padding = append(padding, 0, 0xffffffff)
padding = append(padding, output[:]...)
fullPadding := padding
for i := 2; i < N_PACKED_INSTANCES; i++ {
fullPadding = append(fullPadding, padding...)
}
data := Uint32SliceToMRSlice(fullPadding)
_, err = vm.Segments.LoadData(blake2sPtrEnd, &data)
return err
}

func exampleBlake2sCompress(ids IdsManager, vm *VirtualMachine) error {
// Fetch ids variables
blake2sStart, err := ids.GetRelocatable("blake2s_start", vm)
if err != nil {
return err
}
output, err := ids.GetRelocatable("output", vm)
if err != nil {
return err
}
nBytesFelt, err := ids.GetFelt("n_bytes", vm)
if err != nil {
return err
}
nBytes, err := nBytesFelt.ToU32()
if err != nil {
return err
}
// Hint Logic
message, err := getUint32MemoryRange(blake2sStart, 0, 16, &vm.Segments)
if err != nil {
return err
}
modifiedIv := IV()
modifiedIv[0] = modifiedIv[0] ^ 0x01010020
outputState := Blake2sCompress(modifiedIv, [16]uint32(message), nBytes, 0, 0xffffffff, 0)
outputData := Uint32SliceToMRSlice(outputState)
_, err = vm.Segments.LoadData(output, &outputData)
return err
}
76 changes: 76 additions & 0 deletions pkg/hints/blake2s_hints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,79 @@ func TestBlake2sFinaizeOk(t *testing.T) {
t.Errorf("Wrong/No data loaded.\n Expected: %v.\n Got: %v", expectedDataSegment, dataSegment)
}
}

func TestBlake2sFinaizeV3Ok(t *testing.T) {
vm := NewVirtualMachine()
vm.Segments.AddSegment()
data := vm.Segments.AddSegment()
idsManager := SetupIdsForTest(
map[string][]*MaybeRelocatable{
"blake2s_ptr_end": {NewMaybeRelocatableRelocatable(data)},
},
vm,
)
hintProcessor := CairoVmHintProcessor{}
hintData := any(HintData{
Ids: idsManager,
Code: BLAKE2S_FINALIZE_V3,
})
err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil)
if err != nil {
t.Errorf("BLAKE2S_FINALIZE_V3 hint test failed with error %s", err)
}
// Check the data segment
dataSegment, err := vm.Segments.GetFeltRange(data, 204)

expectedDataSegment := []Felt{
FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(),
FeltFromUint(1795745351), FeltFromUint(3144134277), FeltFromUint(1013904242), FeltFromUint(2773480762), FeltFromUint(1359893119), FeltFromUint(2600822924), FeltFromUint(528734635), FeltFromUint(1541459225), FeltZero(), FeltFromUint(4294967295), FeltFromUint(813310313),
FeltFromUint(2491453561), FeltFromUint(3491828193), FeltFromUint(2085238082), FeltFromUint(1219908895), FeltFromUint(514171180), FeltFromUint(4245497115), FeltFromUint(4193177630),

FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(),
FeltFromUint(1795745351), FeltFromUint(3144134277), FeltFromUint(1013904242), FeltFromUint(2773480762), FeltFromUint(1359893119), FeltFromUint(2600822924), FeltFromUint(528734635), FeltFromUint(1541459225), FeltZero(), FeltFromUint(4294967295), FeltFromUint(813310313),
FeltFromUint(2491453561), FeltFromUint(3491828193), FeltFromUint(2085238082), FeltFromUint(1219908895), FeltFromUint(514171180), FeltFromUint(4245497115), FeltFromUint(4193177630),

FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(),
FeltFromUint(1795745351), FeltFromUint(3144134277), FeltFromUint(1013904242), FeltFromUint(2773480762), FeltFromUint(1359893119), FeltFromUint(2600822924), FeltFromUint(528734635), FeltFromUint(1541459225), FeltZero(), FeltFromUint(4294967295), FeltFromUint(813310313),
FeltFromUint(2491453561), FeltFromUint(3491828193), FeltFromUint(2085238082), FeltFromUint(1219908895), FeltFromUint(514171180), FeltFromUint(4245497115), FeltFromUint(4193177630),

FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(),
FeltFromUint(1795745351), FeltFromUint(3144134277), FeltFromUint(1013904242), FeltFromUint(2773480762), FeltFromUint(1359893119), FeltFromUint(2600822924), FeltFromUint(528734635), FeltFromUint(1541459225), FeltZero(), FeltFromUint(4294967295), FeltFromUint(813310313),
FeltFromUint(2491453561), FeltFromUint(3491828193), FeltFromUint(2085238082), FeltFromUint(1219908895), FeltFromUint(514171180), FeltFromUint(4245497115), FeltFromUint(4193177630),

FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(),
FeltFromUint(1795745351), FeltFromUint(3144134277), FeltFromUint(1013904242), FeltFromUint(2773480762), FeltFromUint(1359893119), FeltFromUint(2600822924), FeltFromUint(528734635), FeltFromUint(1541459225), FeltZero(), FeltFromUint(4294967295), FeltFromUint(813310313),
FeltFromUint(2491453561), FeltFromUint(3491828193), FeltFromUint(2085238082), FeltFromUint(1219908895), FeltFromUint(514171180), FeltFromUint(4245497115), FeltFromUint(4193177630),

FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(), FeltZero(),
FeltFromUint(1795745351), FeltFromUint(3144134277), FeltFromUint(1013904242), FeltFromUint(2773480762), FeltFromUint(1359893119), FeltFromUint(2600822924), FeltFromUint(528734635), FeltFromUint(1541459225), FeltZero(), FeltFromUint(4294967295), FeltFromUint(813310313),
FeltFromUint(2491453561), FeltFromUint(3491828193), FeltFromUint(2085238082), FeltFromUint(1219908895), FeltFromUint(514171180), FeltFromUint(4245497115), FeltFromUint(4193177630),
}
if err != nil || !reflect.DeepEqual(dataSegment, expectedDataSegment) {
t.Errorf("Wrong/No data loaded.\n Expected: %v.\n Got: %v", expectedDataSegment, dataSegment)
}
}

func TestExampleBlake2sCompressEmptyInput(t *testing.T) {
vm := NewVirtualMachine()
vm.Segments.AddSegment()
output := vm.Segments.AddSegment()
blake2sStart := vm.Segments.AddSegment()
idsManager := SetupIdsForTest(
map[string][]*MaybeRelocatable{
"output": {NewMaybeRelocatableRelocatable(output)},
"blake2s_start": {NewMaybeRelocatableRelocatable(blake2sStart)},
"n_bytes": {NewMaybeRelocatableFelt(FeltOne())},
},
vm,
)
hintProcessor := CairoVmHintProcessor{}
hintData := any(HintData{
Ids: idsManager,
Code: EXAMPLE_BLAKE2S_COMPRESS,
})
err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil)
if err == nil {
t.Errorf("EXAMPLE_BLAKE2S_COMPRESS hint test should have failed")
}
}
58 changes: 58 additions & 0 deletions pkg/hints/hint_codes/blake2s_hint_codes.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,61 @@ output = blake2s_compress(
)
padding = (modified_iv + message + [0, 0xffffffff] + output) * (_n_packed_instances - 1)
segments.write_arg(ids.blake2s_ptr_end, padding)`

const BLAKE2S_FINALIZE_V2 = `# Add dummy pairs of input and output.
from starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress

_n_packed_instances = int(ids.N_PACKED_INSTANCES)
assert 0 <= _n_packed_instances < 20
_blake2s_input_chunk_size_felts = int(ids.BLAKE2S_INPUT_CHUNK_SIZE_FELTS)
assert 0 <= _blake2s_input_chunk_size_felts < 100

message = [0] * _blake2s_input_chunk_size_felts
modified_iv = [IV[0] ^ 0x01010020] + IV[1:]
output = blake2s_compress(
message=message,
h=modified_iv,
t0=0,
t1=0,
f0=0xffffffff,
f1=0,
)
padding = (modified_iv + message + [0, 0xffffffff] + output) * (_n_packed_instances - 1)
segments.write_arg(ids.blake2s_ptr_end, padding)`

const BLAKE2S_FINALIZE_V3 = `# Add dummy pairs of input and output.
from starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress

_n_packed_instances = int(ids.N_PACKED_INSTANCES)
assert 0 <= _n_packed_instances < 20
_blake2s_input_chunk_size_felts = int(ids.BLAKE2S_INPUT_CHUNK_SIZE_FELTS)
assert 0 <= _blake2s_input_chunk_size_felts < 100

message = [0] * _blake2s_input_chunk_size_felts
modified_iv = [IV[0] ^ 0x01010020] + IV[1:]
output = blake2s_compress(
message=message,
h=modified_iv,
t0=0,
t1=0,
f0=0xffffffff,
f1=0,
)
padding = (message + modified_iv + [0, 0xffffffff] + output) * (_n_packed_instances - 1)
segments.write_arg(ids.blake2s_ptr_end, padding)`

const EXAMPLE_BLAKE2S_COMPRESS = `from starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress

_blake2s_input_chunk_size_felts = int(ids.BLAKE2S_INPUT_CHUNK_SIZE_FELTS)
assert 0 <= _blake2s_input_chunk_size_felts < 100

new_state = blake2s_compress(
message=memory.get_range(ids.blake2s_start, _blake2s_input_chunk_size_felts),
h=[IV[0] ^ 0x01010020] + IV[1:],
t0=ids.n_bytes,
t1=0,
f0=0xffffffff,
f1=0,
)

segments.write_arg(ids.output, new_state)`
3 changes: 3 additions & 0 deletions pkg/hints/hint_codes/sha256_hint_codes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package hint_codes

const SHA256_INPUT = "ids.full_word = int(ids.n_bytes >= 4)"
8 changes: 7 additions & 1 deletion pkg/hints/hint_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,14 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any,
return verifyZero(data.Ids, vm, execScopes, hint_utils.SECP_P_V2())
case BLAKE2S_ADD_UINT256_BIGEND:
return blake2sAddUint256Bigend(data.Ids, vm)
case BLAKE2S_FINALIZE:
case BLAKE2S_FINALIZE, BLAKE2S_FINALIZE_V2:
return blake2sFinalize(data.Ids, vm)
case BLAKE2S_FINALIZE_V3:
return blake2sFinalizeV3(data.Ids, vm)
case SHA256_INPUT:
return sha256Input(data.Ids, vm)
case EXAMPLE_BLAKE2S_COMPRESS:
return exampleBlake2sCompress(data.Ids, vm)
default:
return errors.Errorf("Unknown Hint: %s", data.Code)
}
Expand Down
19 changes: 19 additions & 0 deletions pkg/hints/sha256_hints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package hints

import (
. "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils"
. "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks"
. "github.com/lambdaclass/cairo-vm.go/pkg/vm"
. "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
)

func sha256Input(ids IdsManager, vm *VirtualMachine) error {
nBytes, err := ids.GetFelt("n_bytes", vm)
if err != nil {
return err
}
if nBytes.Cmp(FeltFromUint(4)) != -1 {
return ids.Insert("full_word", NewMaybeRelocatableFelt(FeltOne()), vm)
}
return ids.Insert("full_word", NewMaybeRelocatableFelt(FeltZero()), vm)
}
64 changes: 64 additions & 0 deletions pkg/hints/sha256_hints_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package hints_test

import (
"testing"

. "github.com/lambdaclass/cairo-vm.go/pkg/hints"
. "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes"
. "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils"
. "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks"
. "github.com/lambdaclass/cairo-vm.go/pkg/vm"
. "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
)

func TestSha256InputFalse(t *testing.T) {
vm := NewVirtualMachine()
vm.Segments.AddSegment()
idsManager := SetupIdsForTest(
map[string][]*MaybeRelocatable{
"n_bytes": {NewMaybeRelocatableFelt(FeltFromUint64(2))},
"full_word": {nil},
},
vm,
)
hintProcessor := CairoVmHintProcessor{}
hintData := any(HintData{
Ids: idsManager,
Code: SHA256_INPUT,
})
err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil)
if err != nil {
t.Errorf("SHA256_INPUT hint test failed with error %s", err)
}
// Check ids.full_word
fullWord, err := idsManager.GetFelt("full_word", vm)
if err != nil || fullWord.Cmp(FeltZero()) != 0 {
t.Error("Wrong/No value inserted into ids.full_word")
}
}

func TestSha256InputTrue(t *testing.T) {
vm := NewVirtualMachine()
vm.Segments.AddSegment()
idsManager := SetupIdsForTest(
map[string][]*MaybeRelocatable{
"n_bytes": {NewMaybeRelocatableFelt(FeltFromUint64(8))},
"full_word": {nil},
},
vm,
)
hintProcessor := CairoVmHintProcessor{}
hintData := any(HintData{
Ids: idsManager,
Code: SHA256_INPUT,
})
err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil)
if err != nil {
t.Errorf("SHA256_INPUT hint test failed with error %s", err)
}
// Check ids.full_word
fullWord, err := idsManager.GetFelt("full_word", vm)
if err != nil || fullWord.Cmp(FeltOne()) != 0 {
t.Error("Wrong/No value inserted into ids.full_word")
}
}
8 changes: 8 additions & 0 deletions pkg/vm/cairo_run/cairo_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,14 @@ func TestBlake2sIntegrationTests(t *testing.T) {
testProgram("blake2s_integration_tests", t)
}

func TestFinalizeBlake2sV2(t *testing.T) {
testProgram("finalize_blake2s_v2", t)
}

func TestExampleBlake2s(t *testing.T) {
testProgram("example_blake2s", t)
}

func TestUint256Integration(t *testing.T) {
testProgram("uint256_integration_tests", t)
}
Expand Down
Loading