@ -0,0 +1,190 @@ |
|||||
|
package sha512 |
||||
|
|
||||
|
import ( |
||||
|
"github.com/consensys/gnark/frontend" |
||||
|
) |
||||
|
|
||||
|
|
||||
|
func Sha512compression(api frontend.API, hin, inp []frontend.Variable) ([]frontend.Variable) { |
||||
|
if len(hin) != 512 { panic("bad length") } |
||||
|
if len(inp) != 1024 { panic("bad length") } |
||||
|
|
||||
|
var ct_k [80][]frontend.Variable |
||||
|
for i := 0; i < 80; i++ { |
||||
|
ct_k[i] = K512(i) |
||||
|
} |
||||
|
|
||||
|
var a [81][64]frontend.Variable |
||||
|
var b [81][64]frontend.Variable |
||||
|
var c [81][64]frontend.Variable |
||||
|
var d [81][64]frontend.Variable |
||||
|
var e [81][64]frontend.Variable |
||||
|
var f [81][64]frontend.Variable |
||||
|
var g [81][64]frontend.Variable |
||||
|
var h [81][64]frontend.Variable |
||||
|
var w [80][64]frontend.Variable |
||||
|
|
||||
|
for t := 0; t < 80; t++ { |
||||
|
if t < 16 { |
||||
|
for k := 0; k < 64; k++ { |
||||
|
w[t][k] = inp[t*64+63-k] |
||||
|
} |
||||
|
} else { |
||||
|
w[t] = SigmaPlus512(w[t-2], w[t-7], w[t-15], w[t-16]) |
||||
|
} |
||||
|
// if (t<16) {
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// w[t][k] <== inp[t*64+63-k];
|
||||
|
// }
|
||||
|
// } else {
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// sigmaPlus[t-16].in2[k] <== w[t-2][k];
|
||||
|
// sigmaPlus[t-16].in7[k] <== w[t-7][k];
|
||||
|
// sigmaPlus[t-16].in15[k] <== w[t-15][k];
|
||||
|
// sigmaPlus[t-16].in16[k] <== w[t-16][k];
|
||||
|
// }
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// w[t][k] <== sigmaPlus[t-16].out[k];
|
||||
|
// }
|
||||
|
// }
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
for k := 0; k < 64; k++ { |
||||
|
a[0][k] = hin[k] |
||||
|
b[0][k] = hin[64*1 + k] |
||||
|
c[0][k] = hin[64*2 + k] |
||||
|
d[0][k] = hin[64*3 + k] |
||||
|
e[0][k] = hin[64*4 + k] |
||||
|
f[0][k] = hin[64*5 + k] |
||||
|
g[0][k] = hin[64*6 + k] |
||||
|
h[0][k] = hin[64*7 + k] |
||||
|
} |
||||
|
// for (k=0; k<64; k++ ) {
|
||||
|
// a[0][k] <== hin[k];
|
||||
|
// b[0][k] <== hin[64*1 + k];
|
||||
|
// c[0][k] <== hin[64*2 + k];
|
||||
|
// d[0][k] <== hin[64*3 + k];
|
||||
|
// e[0][k] <== hin[64*4 + k];
|
||||
|
// f[0][k] <== hin[64*5 + k];
|
||||
|
// g[0][k] <== hin[64*6 + k];
|
||||
|
// h[0][k] <== hin[64*7 + k];
|
||||
|
// }
|
||||
|
|
||||
|
|
||||
|
for t := 0; t < 80; t++ { |
||||
|
t1 := T1_512(h[t], e[t], f[t], g[t], ct_k[t], w[t]) |
||||
|
t2 := T2_512(a[t], b[t], c[t]) |
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// t1[t].h[k] <== h[t][k];
|
||||
|
// t1[t].e[k] <== e[t][k];
|
||||
|
// t1[t].f[k] <== f[t][k];
|
||||
|
// t1[t].g[k] <== g[t][k];
|
||||
|
// t1[t].k[k] <== ct_k[t].out[k];
|
||||
|
// t1[t].w[k] <== w[t][k];
|
||||
|
|
||||
|
// t2[t].a[k] <== a[t][k];
|
||||
|
// t2[t].b[k] <== b[t][k];
|
||||
|
// t2[t].c[k] <== c[t][k];
|
||||
|
// }
|
||||
|
|
||||
|
sume := BinSum(d[t], t1) |
||||
|
suma := BinSum(t1, t2) |
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// sume[t].in[0][k] <== d[t][k];
|
||||
|
// sume[t].in[1][k] <== t1[t].out[k];
|
||||
|
|
||||
|
// suma[t].in[0][k] <== t1[t].out[k];
|
||||
|
// suma[t].in[1][k] <== t2[t].out[k];
|
||||
|
// }
|
||||
|
|
||||
|
for k := 0; k < 64; k++ { |
||||
|
h[t+1][k] = g[t][k]; |
||||
|
g[t+1][k] = f[t][k]; |
||||
|
f[t+1][k] = e[t][k]; |
||||
|
e[t+1][k] = sume[k]; |
||||
|
d[t+1][k] = c[t][k]; |
||||
|
c[t+1][k] = b[t][k]; |
||||
|
b[t+1][k] = a[t][k]; |
||||
|
a[t+1][k] = suma[k]; |
||||
|
} |
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// h[t+1][k] <== g[t][k];
|
||||
|
// g[t+1][k] <== f[t][k];
|
||||
|
// f[t+1][k] <== e[t][k];
|
||||
|
// e[t+1][k] <== sume[t].out[k];
|
||||
|
// d[t+1][k] <== c[t][k];
|
||||
|
// c[t+1][k] <== b[t][k];
|
||||
|
// b[t+1][k] <== a[t][k];
|
||||
|
// a[t+1][k] <== suma[t].out[k];
|
||||
|
// }
|
||||
|
} |
||||
|
|
||||
|
var fsum_in [8][2][64]frontend.Variable |
||||
|
|
||||
|
for k := 0; k < 64; k++ { |
||||
|
fsum[0][0][k] = hin[64*0+k] |
||||
|
fsum[0][1][k] = a[80][k] |
||||
|
fsum[1][0][k] = hin[64*1+k] |
||||
|
fsum[1][1][k] = b[80][k] |
||||
|
fsum[2][0][k] = hin[64*2+k] |
||||
|
fsum[2][1][k] = c[80][k] |
||||
|
fsum[3][0][k] = hin[64*3+k] |
||||
|
fsum[3][1][k] = d[80][k] |
||||
|
fsum[4][0][k] = hin[64*4+k] |
||||
|
fsum[4][1][k] = e[80][k] |
||||
|
fsum[5][0][k] = hin[64*5+k] |
||||
|
fsum[5][1][k] = f[80][k] |
||||
|
fsum[6][0][k] = hin[64*6+k] |
||||
|
fsum[6][1][k] = g[80][k] |
||||
|
fsum[7][0][k] = hin[64*7+k] |
||||
|
fsum[7][1][k] = h[80][k] |
||||
|
} |
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// fsum[0].in[0][k] <== hin[64*0+k];
|
||||
|
// fsum[0].in[1][k] <== a[80][k];
|
||||
|
// fsum[1].in[0][k] <== hin[64*1+k];
|
||||
|
// fsum[1].in[1][k] <== b[80][k];
|
||||
|
// fsum[2].in[0][k] <== hin[64*2+k];
|
||||
|
// fsum[2].in[1][k] <== c[80][k];
|
||||
|
// fsum[3].in[0][k] <== hin[64*3+k];
|
||||
|
// fsum[3].in[1][k] <== d[80][k];
|
||||
|
// fsum[4].in[0][k] <== hin[64*4+k];
|
||||
|
// fsum[4].in[1][k] <== e[80][k];
|
||||
|
// fsum[5].in[0][k] <== hin[64*5+k];
|
||||
|
// fsum[5].in[1][k] <== f[80][k];
|
||||
|
// fsum[6].in[0][k] <== hin[64*6+k];
|
||||
|
// fsum[6].in[1][k] <== g[80][k];
|
||||
|
// fsum[7].in[0][k] <== hin[64*7+k];
|
||||
|
// fsum[7].in[1][k] <== h[80][k];
|
||||
|
// }
|
||||
|
|
||||
|
var fsum [8][]frontend.Variable |
||||
|
for i := 0; i < 8; i++ { |
||||
|
fsum[i] = BinSum(fsum_in[i][0], fsum_in[i][1]) |
||||
|
} |
||||
|
|
||||
|
var out [512]frontend.Variable |
||||
|
|
||||
|
for k := 0; k < 64; k++ { |
||||
|
out[63-k] = fsum[0][k] |
||||
|
out[64+63-k] = fsum[1][k] |
||||
|
out[128+63-k] = fsum[2][k] |
||||
|
out[192+63-k] = fsum[3][k] |
||||
|
out[256+63-k] = fsum[4][k] |
||||
|
out[320+63-k] = fsum[5][k] |
||||
|
out[384+63-k] = fsum[6][k] |
||||
|
out[448+63-k] = fsum[7][k] |
||||
|
} |
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// out[63-k] <== fsum[0].out[k];
|
||||
|
// out[64+63-k] <== fsum[1].out[k];
|
||||
|
// out[128+63-k] <== fsum[2].out[k];
|
||||
|
// out[192+63-k] <== fsum[3].out[k];
|
||||
|
// out[256+63-k] <== fsum[4].out[k];
|
||||
|
// out[320+63-k] <== fsum[5].out[k];
|
||||
|
// out[384+63-k] <== fsum[6].out[k];
|
||||
|
// out[448+63-k] <== fsum[7].out[k];
|
||||
|
// }
|
||||
|
return out |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
package sha512 |
||||
|
|
||||
|
import ( |
||||
|
"github.com/consensys/gnark/frontend" |
||||
|
) |
||||
|
|
||||
|
func ShR512(api frontend.API, in []frontend.Variable, r int) ([]frontend.Variable) { |
||||
|
n := len(in) |
||||
|
out := make([] frontend.Variable, n) |
||||
|
for i := 0; i < n; i++ { |
||||
|
if i+r >= n { |
||||
|
out[i] = 0 |
||||
|
} else { |
||||
|
out[i] = in[i+r] |
||||
|
} |
||||
|
} |
||||
|
return out |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// template ShR512(n, r) {
|
||||
|
// signal input in[n];
|
||||
|
// signal output out[n];
|
||||
|
|
||||
|
// for (var i=0; i<n; i++) {
|
||||
|
// if (i+r >= n) {
|
||||
|
// out[i] <== 0;
|
||||
|
// } else {
|
||||
|
// out[i] <== in[ i+r ];
|
||||
|
// }
|
||||
|
// }
|
||||
|
// }
|
@ -0,0 +1,81 @@ |
|||||
|
package sha512 |
||||
|
|
||||
|
import ( |
||||
|
"github.com/consensys/gnark/frontend" |
||||
|
) |
||||
|
|
||||
|
|
||||
|
func SmallSigma512(api frontend.API, in []frontend.Variable, ra, rb, rc int) ([]frontend.Variable) { |
||||
|
if len(in) != 64 { panic("bad length") } |
||||
|
|
||||
|
rota := RotR512(in, ra) |
||||
|
rotb := RotR512(in, rb) |
||||
|
shrc := ShR512(in, rc) |
||||
|
|
||||
|
return Xor3_512(rota, rotb, shrc) |
||||
|
} |
||||
|
|
||||
|
// template SmallSigma512(ra, rb, rc) {
|
||||
|
// signal input in[64];
|
||||
|
// signal output out[64];
|
||||
|
// var k;
|
||||
|
|
||||
|
// component rota = RotR512(64, ra);
|
||||
|
// component rotb = RotR512(64, rb);
|
||||
|
// component shrc = ShR512(64, rc);
|
||||
|
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// rota.in[k] <== in[k];
|
||||
|
// rotb.in[k] <== in[k];
|
||||
|
// shrc.in[k] <== in[k];
|
||||
|
// }
|
||||
|
|
||||
|
// component xor3 = Xor3_512(64);
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// xor3.a[k] <== rota.out[k];
|
||||
|
// xor3.b[k] <== rotb.out[k];
|
||||
|
// xor3.c[k] <== shrc.out[k];
|
||||
|
// }
|
||||
|
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// out[k] <== xor3.out[k];
|
||||
|
// }
|
||||
|
// }
|
||||
|
|
||||
|
func BigSigma512(api frontend.API, in []frontend.Variable, ra, rb, rc int) ([]frontend.Variable) { |
||||
|
if len(in) != 64 { panic("bad length") } |
||||
|
|
||||
|
rota := RotR512(in, ra) |
||||
|
rotb := RotR512(in, rb) |
||||
|
rotc := RotR512(in, rc) |
||||
|
|
||||
|
return Xor3_512(rota, rotb, rotc) |
||||
|
} |
||||
|
|
||||
|
// template BigSigma512(ra, rb, rc) {
|
||||
|
// signal input in[64];
|
||||
|
// signal output out[64];
|
||||
|
// var k;
|
||||
|
|
||||
|
// component rota = RotR512(64, ra);
|
||||
|
// component rotb = RotR512(64, rb);
|
||||
|
// component rotc = RotR512(64, rc);
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// rota.in[k] <== in[k];
|
||||
|
// rotb.in[k] <== in[k];
|
||||
|
// rotc.in[k] <== in[k];
|
||||
|
// }
|
||||
|
|
||||
|
// component xor3 = Xor3_512(64);
|
||||
|
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// xor3.a[k] <== rota.out[k];
|
||||
|
// xor3.b[k] <== rotb.out[k];
|
||||
|
// xor3.c[k] <== rotc.out[k];
|
||||
|
// }
|
||||
|
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// out[k] <== xor3.out[k];
|
||||
|
// }
|
||||
|
// }
|
||||
|
|
@ -0,0 +1,44 @@ |
|||||
|
package sha512 |
||||
|
|
||||
|
import ( |
||||
|
"github.com/consensys/gnark/frontend" |
||||
|
) |
||||
|
|
||||
|
|
||||
|
func SigmaPlus512(api frontend.API, in2, in7, in15, in16 []frontend.Variable) ([]frontend.Variable) { |
||||
|
if len(in2) != 64 { panic("bad length") } |
||||
|
|
||||
|
sigma1 := SmallSigma512(in2, 19, 61, 6) |
||||
|
sigma0 := SmallSigma512(in15, 1, 8, 7) |
||||
|
|
||||
|
return BinSum(sigma1, in7, sigma0, in16) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// template SigmaPlus512() {
|
||||
|
// signal input in2[64];
|
||||
|
// signal input in7[64];
|
||||
|
// signal input in15[64];
|
||||
|
// signal input in16[64];
|
||||
|
// signal output out[64];
|
||||
|
// var k;
|
||||
|
|
||||
|
// component sigma1 = SmallSigma512(19,61,6);
|
||||
|
// component sigma0 = SmallSigma512(1, 8, 7);
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// sigma1.in[k] <== in2[k];
|
||||
|
// sigma0.in[k] <== in15[k];
|
||||
|
// }
|
||||
|
|
||||
|
// component sum = BinSum(64, 4);
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// sum.in[0][k] <== sigma1.out[k];
|
||||
|
// sum.in[1][k] <== in7[k];
|
||||
|
// sum.in[2][k] <== sigma0.out[k];
|
||||
|
// sum.in[3][k] <== in16[k];
|
||||
|
// }
|
||||
|
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// out[k] <== sum.out[k];
|
||||
|
// }
|
||||
|
// }
|
@ -0,0 +1,55 @@ |
|||||
|
package sha512 |
||||
|
|
||||
|
import ( |
||||
|
"github.com/consensys/gnark/frontend" |
||||
|
) |
||||
|
|
||||
|
|
||||
|
func T1_512(api frontend.API, h, e, f, g, k, w []frontend.Variable) ([]frontend.Variable) { |
||||
|
if len(h) != 64 { panic("bad length") } |
||||
|
if len(e) != 64 { panic("bad length") } |
||||
|
if len(f) != 64 { panic("bad length") } |
||||
|
if len(g) != 64 { panic("bad length") } |
||||
|
if len(k) != 64 { panic("bad length") } |
||||
|
if len(w) != 64 { panic("bad length") } |
||||
|
|
||||
|
ch := Ch_t512(e, f, g) |
||||
|
bigsigma1 := BigSigma512(e, 14, 18, 41) |
||||
|
|
||||
|
return BinSum(h, bigsigma1, ch, k, w) |
||||
|
} |
||||
|
|
||||
|
// template T1_512() {
|
||||
|
// signal input h[64];
|
||||
|
// signal input e[64];
|
||||
|
// signal input f[64];
|
||||
|
// signal input g[64];
|
||||
|
// signal input k[64];
|
||||
|
// signal input w[64];
|
||||
|
// signal output out[64];
|
||||
|
|
||||
|
// var ki;
|
||||
|
|
||||
|
// component ch = Ch_t512(64);
|
||||
|
// component bigsigma1 = BigSigma512(14, 18, 41);
|
||||
|
|
||||
|
// for (ki=0; ki<64; ki++) {
|
||||
|
// bigsigma1.in[ki] <== e[ki];
|
||||
|
// ch.a[ki] <== e[ki];
|
||||
|
// ch.b[ki] <== f[ki];
|
||||
|
// ch.c[ki] <== g[ki];
|
||||
|
// }
|
||||
|
|
||||
|
// component sum = BinSum(64, 5);
|
||||
|
// for (ki=0; ki<64; ki++) {
|
||||
|
// sum.in[0][ki] <== h[ki];
|
||||
|
// sum.in[1][ki] <== bigsigma1.out[ki];
|
||||
|
// sum.in[2][ki] <== ch.out[ki];
|
||||
|
// sum.in[3][ki] <== k[ki];
|
||||
|
// sum.in[4][ki] <== w[ki];
|
||||
|
// }
|
||||
|
|
||||
|
// for (ki=0; ki<64; ki++) {
|
||||
|
// out[ki] <== sum.out[ki];
|
||||
|
// }
|
||||
|
// }
|
@ -0,0 +1,45 @@ |
|||||
|
package sha512 |
||||
|
|
||||
|
import ( |
||||
|
"github.com/consensys/gnark/frontend" |
||||
|
) |
||||
|
|
||||
|
|
||||
|
func T2_512(api frontend.API, a, b, c []frontend.Variable) ([]frontend.Variable) { |
||||
|
if len(a) != 64 { panic("bad length") } |
||||
|
if len(b) != 64 { panic("bad length") } |
||||
|
if len(c) != 64 { panic("bad length") } |
||||
|
|
||||
|
bigsigma0 := BigSigma512(a, 28, 34, 39) |
||||
|
maj := Maj_t512(a, b, c) |
||||
|
|
||||
|
return BinSum(maj, bigsigma0) |
||||
|
} |
||||
|
|
||||
|
// template T2_512() {
|
||||
|
// signal input a[64];
|
||||
|
// signal input b[64];
|
||||
|
// signal input c[64];
|
||||
|
// signal output out[64];
|
||||
|
// var k;
|
||||
|
|
||||
|
// component bigsigma0 = BigSigma512(28, 34, 39);
|
||||
|
// component maj = Maj_t512(64);
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// bigsigma0.in[k] <== a[k];
|
||||
|
// maj.a[k] <== a[k];
|
||||
|
// maj.b[k] <== b[k];
|
||||
|
// maj.c[k] <== c[k];
|
||||
|
// }
|
||||
|
|
||||
|
// component sum = BinSum(64, 2);
|
||||
|
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// sum.in[0][k] <== bigsigma0.out[k];
|
||||
|
// sum.in[1][k] <== maj.out[k];
|
||||
|
// }
|
||||
|
|
||||
|
// for (k=0; k<64; k++) {
|
||||
|
// out[k] <== sum.out[k];
|
||||
|
// }
|
||||
|
// }
|
@ -0,0 +1,35 @@ |
|||||
|
package sha512 |
||||
|
|
||||
|
import ( |
||||
|
"github.com/consensys/gnark/frontend" |
||||
|
) |
||||
|
|
||||
|
func Xor3_512(api frontend.API, a, b, c []frontend.Variable) ([]frontend.Variable) { |
||||
|
n := len(a) |
||||
|
if len(a) != n { panic("bad length") } |
||||
|
if len(b) != n { panic("bad length") } |
||||
|
if len(c) != n { panic("bad length") } |
||||
|
out := make([]frontend.Variable, n) |
||||
|
for k := 0; k < n; k++ { |
||||
|
mid := api.Mul(b[k], c[k]) |
||||
|
p := api.Add(1, api.Mul(-2, b[k]), api.Mul(-2, c[k]), api.Mul(4, mid[k])) |
||||
|
q := api.Mul(a[k], inner) |
||||
|
out[k] = api.Add(q, b[k], c[k], api.Mul(-2, mid[k])) |
||||
|
// TODO: try doing this instead:
|
||||
|
// out[k] = api.Xor(a[k], api.Xor(b[k], c[k]))
|
||||
|
} |
||||
|
return out |
||||
|
} |
||||
|
|
||||
|
// template Xor3_512(n) {
|
||||
|
// signal input a[n];
|
||||
|
// signal input b[n];
|
||||
|
// signal input c[n];
|
||||
|
// signal output out[n];
|
||||
|
// signal mid[n];
|
||||
|
|
||||
|
// for (var k=0; k<n; k++) {
|
||||
|
// mid[k] <== b[k]*c[k];
|
||||
|
// out[k] <== a[k] * (1 -2*b[k] -2*c[k] +4*mid[k]) + b[k] + c[k] -2*mid[k];
|
||||
|
// }
|
||||
|
// }
|