Skip to content

Commit

Permalink
Implement Blake2s hash (#310)
Browse files Browse the repository at this point in the history
* Begin implemneting blake2s

* Finish blake2s impl

* Add unit test

* Add more unit tests

---------

Co-authored-by: Pedro Fontana <[email protected]>
  • Loading branch information
fmoletta and pefontana authored Oct 23, 2023
1 parent 66a5863 commit 62f6a55
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 0 deletions.
79 changes: 79 additions & 0 deletions pkg/hints/hint_utils/bake2s_hash_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package hint_utils_test

import (
"reflect"
"testing"

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

func TestBlake2sCompressA(t *testing.T) {
h := [8]uint32{1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225}
message := [16]uint32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
expectedState := []uint32{412110711, 3234706100, 3894970767, 982912411, 937789635, 742982576, 3942558313, 1407547065}
newState := Blake2sCompress(h, message, 2, 0, 4294967295, 0)
if !reflect.DeepEqual(expectedState, newState) {
t.Error("Wrong state returned by Blake2sCompress")
}
}

func TestBlake2sCompressB(t *testing.T) {
h := [8]uint32{1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225}
message := [16]uint32{456710651, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
expectedState := []uint32{1061041453, 3663967611, 2158760218, 836165556, 3696892209, 3887053585, 2675134684, 2201582556}
newState := Blake2sCompress(h, message, 2, 0, 4294967295, 0)
if !reflect.DeepEqual(expectedState, newState) {
t.Error("Wrong state returned by Blake2sCompress")
}
}

func TestBlake2sCompressC(t *testing.T) {
//Hashing "Hello World"
h := [8]uint32{1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225}
message := [16]uint32{1819043144, 1870078063, 6581362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
expectedState := []uint32{939893662, 3935214984, 1704819782, 3912812968, 4211807320, 3760278243, 674188535, 2642110762}
newState := Blake2sCompress(h, message, 9, 0, 4294967295, 0)
if !reflect.DeepEqual(expectedState, newState) {
t.Error("Wrong state returned by Blake2sCompress")
}
}

func TestBlake2sCompressD(t *testing.T) {
h := [8]uint32{1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225}
message := [16]uint32{1819043144, 1870078063, 6581362, 274628678, 715791845, 175498643, 871587583, 0, 0, 0, 0, 0, 0, 0, 0, 0}
expectedState := []uint32{3980510537, 3982966407, 1593299263, 2666882356, 3288094120, 2682988286, 1666615862, 378086837}
newState := Blake2sCompress(h, message, 28, 0, 4294967295, 0)
if !reflect.DeepEqual(expectedState, newState) {
t.Error("Wrong state returned by Blake2sCompress")
}
}

func TestBlake2sCompressE(t *testing.T) {
h := [8]uint32{1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225}
message := [16]uint32{1819043144, 1870078063, 6581362, 274628678, 715791845, 175498643, 871587583, 635963558, 557369694, 1576875962, 215769785, 0, 0, 0, 0, 0}
expectedState := []uint32{3251785223, 1946079609, 2665255093, 3508191500, 3630835628, 3067307230, 3623370123, 656151356}
newState := Blake2sCompress(h, message, 44, 0, 4294967295, 0)
if !reflect.DeepEqual(expectedState, newState) {
t.Error("Wrong state returned by Blake2sCompress")
}
}

func TestBlake2sCompressF(t *testing.T) {
h := [8]uint32{1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225}
message := [16]uint32{1819043144, 1870078063, 6581362, 274628678, 715791845, 175498643, 871587583, 635963558, 557369694, 1576875962, 215769785, 152379578, 585849303, 764739320, 437383930, 74833930}
expectedState := []uint32{2593218707, 3238077801, 914875393, 3462286058, 4028447058, 3174734057, 2001070146, 3741410512}
newState := Blake2sCompress(h, message, 64, 0, 4294967295, 0)
if !reflect.DeepEqual(expectedState, newState) {
t.Error("Wrong state returned by Blake2sCompress")
}
}

func TestBlake2sCompressG(t *testing.T) {
h := [8]uint32{1795745351, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225}
message := [16]uint32{11563522, 43535528, 653255322, 274628678, 73471943, 17549868, 87158958, 635963558, 343656565, 1576875962, 215769785, 152379578, 585849303, 76473202, 437253230, 74833930}
expectedState := []uint32{3496615692, 3252241979, 3771521549, 2125493093, 3240605752, 2885407061, 3962009872, 3845288240}
newState := Blake2sCompress(h, message, 64, 0, 4294967295, 0)
if !reflect.DeepEqual(expectedState, newState) {
t.Error("Wrong state returned by Blake2sCompress")
}
}
133 changes: 133 additions & 0 deletions pkg/hints/hint_utils/blake2s_hash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package hint_utils

func IV() [8]uint32 {
return [8]uint32{
0x6A09E667,
0xBB67AE85,
0x3C6EF372,
0xA54FF53A,
0x510E527F,
0x9B05688C,
0x1F83D9AB,
0x5BE0CD19}
}

func SIGMA() [10][16]uint32 {
return [10][16]uint32{
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
}
}

func rightRot(value uint32, n uint32) uint32 {
return (value >> n) | ((value & ((1 << n) - 1)) << (32 - n))
}

func mix(a uint32, b uint32, c uint32, d uint32, m0 uint32, m1 uint32) (uint32, uint32, uint32, uint32) {
a = a + b + m0
d = rightRot(d^a, 16)
c = c + d
b = rightRot(b^c, 12)
a = a + b + m1
d = rightRot(d^a, 8)
c = c + d
b = rightRot(b^c, 7)
return a, b, c, d
}

func blakeRound(state []uint32, message [16]uint32, sigma [16]uint32) []uint32 {
state[0], state[4], state[8], state[12] = mix(
state[0],
state[4],
state[8],
state[12],
message[sigma[0]],
message[sigma[1]],
)
state[1], state[5], state[9], state[13] = mix(
state[1],
state[5],
state[9],
state[13],
message[sigma[2]],
message[sigma[3]],
)
state[2], state[6], state[10], state[14] = mix(
state[2],
state[6],
state[10],
state[14],
message[sigma[4]],
message[sigma[5]],
)
state[3], state[7], state[11], state[15] = mix(
state[3],
state[7],
state[11],
state[15],
message[sigma[6]],
message[sigma[7]],
)
state[0], state[5], state[10], state[15] = mix(
state[0],
state[5],
state[10],
state[15],
message[sigma[8]],
message[sigma[9]],
)
state[1], state[6], state[11], state[12] = mix(
state[1],
state[6],
state[11],
state[12],
message[sigma[10]],
message[sigma[11]],
)
state[2], state[7], state[8], state[13] = mix(
state[2],
state[7],
state[8],
state[13],
message[sigma[12]],
message[sigma[13]],
)
state[3], state[4], state[9], state[14] = mix(
state[3],
state[4],
state[9],
state[14],
message[sigma[14]],
message[sigma[15]],
)
return state
}

func Blake2sCompress(h [8]uint32, message [16]uint32, t0 uint32, t1 uint32, f0 uint32, f1 uint32) []uint32 {
iv := IV()

state := make([]uint32, 0, 16)

state = append(state, h[:]...)
state = append(state, iv[:4]...)
state = append(state, iv[4]^t0, iv[5]^t1, iv[6]^f0, iv[7]^f1)

for _, sigmaList := range SIGMA() {
state = blakeRound(state, message, sigmaList)
}

newState := make([]uint32, 0, 8)
for i := 0; i < 8; i++ {
newState = append(newState, h[i]^state[i]^state[8+i])
}

return newState
}

0 comments on commit 62f6a55

Please sign in to comment.