|
@ -1,5 +1,7 @@ |
|
|
package sha512 |
|
|
package sha512 |
|
|
|
|
|
|
|
|
|
|
|
// Based on https://gist.github.com/illia-v/7883be942da5d416521375004cecb68f
|
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
"github.com/consensys/gnark/frontend" |
|
|
"github.com/consensys/gnark/frontend" |
|
|
) |
|
|
) |
|
@ -12,8 +14,6 @@ func _right_rotate(n [64]frontend.Variable, bits int) [64]frontend.Variable { |
|
|
} |
|
|
} |
|
|
return result |
|
|
return result |
|
|
} |
|
|
} |
|
|
// def _right_rotate(n: int, bits: int) -> int:
|
|
|
|
|
|
// return (n >> bits) | (n << (64 - bits)) & 0xFFFFFFFFFFFFFFFF
|
|
|
|
|
|
|
|
|
|
|
|
func PySha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variable) { |
|
|
func PySha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variable) { |
|
|
_not := func(x [64]frontend.Variable) [64]frontend.Variable { |
|
|
_not := func(x [64]frontend.Variable) [64]frontend.Variable { |
|
@ -85,29 +85,23 @@ func PySha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variabl |
|
|
api.AssertIsBoolean(v) |
|
|
api.AssertIsBoolean(v) |
|
|
} |
|
|
} |
|
|
mdi := divChecked(len(in), 8) % 128 |
|
|
mdi := divChecked(len(in), 8) % 128 |
|
|
// mdi = len(message_array) % 128
|
|
|
|
|
|
var padding_len int |
|
|
var padding_len int |
|
|
if mdi < 112 { |
|
|
if mdi < 112 { |
|
|
padding_len = 119 - mdi |
|
|
padding_len = 119 - mdi |
|
|
} else { |
|
|
} else { |
|
|
padding_len = 247 - mdi |
|
|
padding_len = 247 - mdi |
|
|
} |
|
|
} |
|
|
// padding_len = 119 - mdi if mdi < 112 else 247 - mdi
|
|
|
|
|
|
message_length_bits := uint64ToBits(uint64(len(in))) |
|
|
message_length_bits := uint64ToBits(uint64(len(in))) |
|
|
// ending = struct.pack('!Q', len(message_array) << 3)
|
|
|
|
|
|
in = append(in, 1) |
|
|
in = append(in, 1) |
|
|
for i := 0; i < 7; i++ { |
|
|
for i := 0; i < 7; i++ { |
|
|
in = append(in, 0) |
|
|
in = append(in, 0) |
|
|
} |
|
|
} |
|
|
// message_array.append(0x80)
|
|
|
|
|
|
for i := 0; i < padding_len * 8; i++ { |
|
|
for i := 0; i < padding_len * 8; i++ { |
|
|
in = append(in, 0) |
|
|
in = append(in, 0) |
|
|
} |
|
|
} |
|
|
// message_array.extend([0] * padding_len)
|
|
|
|
|
|
for i := 0; i < 64; i++ { |
|
|
for i := 0; i < 64; i++ { |
|
|
in = append(in, message_length_bits[i]) |
|
|
in = append(in, message_length_bits[i]) |
|
|
} |
|
|
} |
|
|
// message_array.extend(bytearray(ending))
|
|
|
|
|
|
|
|
|
|
|
|
sha512_hash := Array8_64{ |
|
|
sha512_hash := Array8_64{ |
|
|
uint64ToBits(initial_hash[0]), |
|
|
uint64ToBits(initial_hash[0]), |
|
@ -119,80 +113,46 @@ func PySha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variabl |
|
|
uint64ToBits(initial_hash[6]), |
|
|
uint64ToBits(initial_hash[6]), |
|
|
uint64ToBits(initial_hash[7]), |
|
|
uint64ToBits(initial_hash[7]), |
|
|
} |
|
|
} |
|
|
// sha512_hash = list(initial_hash)
|
|
|
|
|
|
for chunk_start := 0; chunk_start < divChecked(len(in), 8); chunk_start += 128 { |
|
|
for chunk_start := 0; chunk_start < divChecked(len(in), 8); chunk_start += 128 { |
|
|
// for chunk_start in range(0, len(message_array), 128):
|
|
|
|
|
|
chunk := in[chunk_start * 8 : (chunk_start+128) * 8] |
|
|
chunk := in[chunk_start * 8 : (chunk_start+128) * 8] |
|
|
// chunk = message_array[chunk_start:chunk_start + 128]
|
|
|
|
|
|
if len(chunk) != 1024 { panic("bad length") } |
|
|
if len(chunk) != 1024 { panic("bad length") } |
|
|
u := make([]frontend.Variable, 80 * 64) |
|
|
u := make([]frontend.Variable, 80 * 64) |
|
|
for i, _ := range u { |
|
|
for i, _ := range u { |
|
|
u[i] = 0 |
|
|
u[i] = 0 |
|
|
} |
|
|
} |
|
|
// w = [0] * 80
|
|
|
|
|
|
copy(u, chunk) |
|
|
copy(u, chunk) |
|
|
// w[0:16] = struct.unpack('!16Q', chunk)
|
|
|
|
|
|
|
|
|
|
|
|
w := reshape(u) |
|
|
w := reshape(u) |
|
|
|
|
|
|
|
|
for i := 16; i < 80; i++ { |
|
|
for i := 16; i < 80; i++ { |
|
|
// for i in range(16, 80):
|
|
|
|
|
|
s0 := _xor( |
|
|
s0 := _xor( |
|
|
_right_rotate(w[i - 15], 1), |
|
|
_right_rotate(w[i - 15], 1), |
|
|
_right_rotate(w[i - 15], 8), |
|
|
_right_rotate(w[i - 15], 8), |
|
|
_shr(w[i - 15], 7), |
|
|
_shr(w[i - 15], 7), |
|
|
) |
|
|
) |
|
|
// s0 = (
|
|
|
|
|
|
// _right_rotate(w[i - 15], 1) ^
|
|
|
|
|
|
// _right_rotate(w[i - 15], 8) ^
|
|
|
|
|
|
// (w[i - 15] >> 7)
|
|
|
|
|
|
// )
|
|
|
|
|
|
s1 := _xor( |
|
|
s1 := _xor( |
|
|
_right_rotate(w[i - 2], 19), |
|
|
_right_rotate(w[i - 2], 19), |
|
|
_right_rotate(w[i - 2], 61), |
|
|
_right_rotate(w[i - 2], 61), |
|
|
_shr(w[i - 2], 6), |
|
|
_shr(w[i - 2], 6), |
|
|
) |
|
|
) |
|
|
// s1 = (
|
|
|
|
|
|
// _right_rotate(w[i - 2], 19) ^
|
|
|
|
|
|
// _right_rotate(w[i - 2], 61) ^
|
|
|
|
|
|
// (w[i - 2] >> 6)
|
|
|
|
|
|
// )
|
|
|
|
|
|
w[i] = _add(w[i - 16], s0, w[i - 7], s1) |
|
|
w[i] = _add(w[i - 16], s0, w[i - 7], s1) |
|
|
// w[i] = (w[i - 16] + s0 + w[i - 7] + s1) & 0xFFFFFFFFFFFFFFFF
|
|
|
|
|
|
} |
|
|
} |
|
|
a, b, c, d, e, f, g, h := unpack8(sha512_hash) |
|
|
a, b, c, d, e, f, g, h := unpack8(sha512_hash) |
|
|
// a, b, c, d, e, f, g, h = sha512_hash
|
|
|
|
|
|
for i := 0; i < 80; i++ { |
|
|
for i := 0; i < 80; i++ { |
|
|
// for i in range(80):
|
|
|
|
|
|
|
|
|
|
|
|
sum1 := _xor( |
|
|
sum1 := _xor( |
|
|
_right_rotate(e, 14), |
|
|
_right_rotate(e, 14), |
|
|
_right_rotate(e, 18), |
|
|
_right_rotate(e, 18), |
|
|
_right_rotate(e, 41), |
|
|
_right_rotate(e, 41), |
|
|
) |
|
|
) |
|
|
// sum1 = (
|
|
|
|
|
|
// _right_rotate(e, 14) ^
|
|
|
|
|
|
// _right_rotate(e, 18) ^
|
|
|
|
|
|
// _right_rotate(e, 41)
|
|
|
|
|
|
// )
|
|
|
|
|
|
ch := _xor(_and(e, f), _and(_not(e), g)) |
|
|
ch := _xor(_and(e, f), _and(_not(e), g)) |
|
|
// ch = (e & f) ^ (~e & g)
|
|
|
|
|
|
temp1 := _add(h, sum1, ch, uint64ToBits(round_constants[i]), w[i]) |
|
|
temp1 := _add(h, sum1, ch, uint64ToBits(round_constants[i]), w[i]) |
|
|
// temp1 = h + sum1 + ch + round_constants[i] + w[i]
|
|
|
|
|
|
sum0 := _xor( |
|
|
sum0 := _xor( |
|
|
_right_rotate(a, 28), |
|
|
_right_rotate(a, 28), |
|
|
_right_rotate(a, 34), |
|
|
_right_rotate(a, 34), |
|
|
_right_rotate(a, 39), |
|
|
_right_rotate(a, 39), |
|
|
) |
|
|
) |
|
|
// sum0 = (
|
|
|
|
|
|
// _right_rotate(a, 28) ^
|
|
|
|
|
|
// _right_rotate(a, 34) ^
|
|
|
|
|
|
// _right_rotate(a, 39)
|
|
|
|
|
|
// )
|
|
|
|
|
|
maj := _xor(_and(a, b), _and(a, c), _and(b, c)) |
|
|
maj := _xor(_and(a, b), _and(a, c), _and(b, c)) |
|
|
// maj = (a & b) ^ (a & c) ^ (b & c)
|
|
|
|
|
|
temp2 := _add(sum0, maj) |
|
|
temp2 := _add(sum0, maj) |
|
|
// temp2 = sum0 + maj
|
|
|
|
|
|
|
|
|
|
|
|
h = g |
|
|
h = g |
|
|
g = f |
|
|
g = f |
|
@ -202,46 +162,12 @@ func PySha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variabl |
|
|
c = b |
|
|
c = b |
|
|
b = a |
|
|
b = a |
|
|
a = _add(temp1, temp2) |
|
|
a = _add(temp1, temp2) |
|
|
// h = g
|
|
|
|
|
|
// g = f
|
|
|
|
|
|
// f = e
|
|
|
|
|
|
// e = (d + temp1) & 0xFFFFFFFFFFFFFFFF
|
|
|
|
|
|
// d = c
|
|
|
|
|
|
// c = b
|
|
|
|
|
|
// b = a
|
|
|
|
|
|
// a = (temp1 + temp2) & 0xFFFFFFFFFFFFFFFF
|
|
|
|
|
|
// sha512_hash = [
|
|
|
|
|
|
// (x + y) & 0xFFFFFFFFFFFFFFFF
|
|
|
|
|
|
// for x, y in zip(sha512_hash, (a, b, c, d, e, f, g, h))
|
|
|
|
|
|
// ]
|
|
|
|
|
|
} |
|
|
} |
|
|
sha512_hash = zip_add(sha512_hash, Array8_64{a, b, c, d, e, f, g, h}) |
|
|
sha512_hash = zip_add(sha512_hash, Array8_64{a, b, c, d, e, f, g, h}) |
|
|
} |
|
|
} |
|
|
return flatten8(sha512_hash) |
|
|
return flatten8(sha512_hash) |
|
|
// return binascii.hexlify(
|
|
|
|
|
|
// b''.join(struct.pack('!Q', element) for element in sha512_hash),
|
|
|
|
|
|
// ).decode('utf-8')
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if __name__ == "__main__":
|
|
|
|
|
|
// assert sha512('Hello, world!') == (
|
|
|
|
|
|
// 'c1527cd893c124773d811911970c8fe6e857d6df5dc9226bd8a160614c0cd963a4dde'
|
|
|
|
|
|
// 'a2b94bb7d36021ef9d865d5cea294a82dd49a0bb269f51f6e7a57f79421'
|
|
|
|
|
|
// )
|
|
|
|
|
|
// assert sha512('Python') == (
|
|
|
|
|
|
// 'fd9d4d5b7a8a8fae6b1bc099b799110f7e4338606e2610f5d9506a4346e0c3bfbc525'
|
|
|
|
|
|
// 'f4eed1e05aa8c6f46b8efff526ec48b500928a1b341ade5a7855f533932'
|
|
|
|
|
|
// )
|
|
|
|
|
|
// assert sha512('Illia') == (
|
|
|
|
|
|
// '09d4ba2426df452bddacde12436ef528c19e91236dfab2e7e2d45a0c2b450c7744397'
|
|
|
|
|
|
// '67d8c23ed5be08cd50a7aa74b4c7ffda135a2f9ac18b186893a6b052710'
|
|
|
|
|
|
// )
|
|
|
|
|
|
|
|
|
|
|
|
func reshape(u []frontend.Variable) [][64]frontend.Variable { |
|
|
func reshape(u []frontend.Variable) [][64]frontend.Variable { |
|
|
l := divChecked(len(u), 64) |
|
|
l := divChecked(len(u), 64) |
|
|
result := make([][64]frontend.Variable, l) |
|
|
result := make([][64]frontend.Variable, l) |
|
|