From 21c4623956c0dd2e081fe17c9a3169ab77956525 Mon Sep 17 00:00:00 2001 From: Jacob Jackson Date: Tue, 4 Oct 2022 00:21:10 +0000 Subject: [PATCH] draft sha ops --- sha512/ch.go | 4 +- sha512/sha512compression.go | 190 ++++++++++++++++++++++++++++++++++++ sha512/shift.go | 32 ++++++ sha512/sigma.go | 81 +++++++++++++++ sha512/sigmaplus.go | 44 +++++++++ sha512/t1.go | 55 +++++++++++ sha512/t2.go | 45 +++++++++ sha512/xor3.go | 35 +++++++ 8 files changed, 484 insertions(+), 2 deletions(-) create mode 100644 sha512/sha512compression.go create mode 100644 sha512/shift.go create mode 100644 sha512/sigma.go create mode 100644 sha512/sigmaplus.go create mode 100644 sha512/t1.go create mode 100644 sha512/t2.go create mode 100644 sha512/xor3.go diff --git a/sha512/ch.go b/sha512/ch.go index fbfde20..b295dcd 100644 --- a/sha512/ch.go +++ b/sha512/ch.go @@ -4,12 +4,12 @@ import ( "github.com/consensys/gnark/frontend" ) -func Ch_t512(api frontend.API, a, b, c [] frontend.Variable) ([] frontend.Variable) { +func Ch_t512(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) + out := make([]frontend.Variable, n) for k := 0; k < n; k++ { out[k] = api.Add(api.Mul(a[k], api.Sub(b[k], c[k])), c[k]); } diff --git a/sha512/sha512compression.go b/sha512/sha512compression.go new file mode 100644 index 0000000..d614623 --- /dev/null +++ b/sha512/sha512compression.go @@ -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 +} diff --git a/sha512/shift.go b/sha512/shift.go new file mode 100644 index 0000000..fd55815 --- /dev/null +++ b/sha512/shift.go @@ -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) { +// out[i] <== 0; +// } else { +// out[i] <== in[ i+r ]; +// } +// } +// } diff --git a/sha512/sigma.go b/sha512/sigma.go new file mode 100644 index 0000000..2e62eeb --- /dev/null +++ b/sha512/sigma.go @@ -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]; +// } +// } + diff --git a/sha512/sigmaplus.go b/sha512/sigmaplus.go new file mode 100644 index 0000000..d2e4f5a --- /dev/null +++ b/sha512/sigmaplus.go @@ -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]; +// } +// } diff --git a/sha512/t1.go b/sha512/t1.go new file mode 100644 index 0000000..69e3de6 --- /dev/null +++ b/sha512/t1.go @@ -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]; +// } +// } diff --git a/sha512/t2.go b/sha512/t2.go new file mode 100644 index 0000000..52e225a --- /dev/null +++ b/sha512/t2.go @@ -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]; +// } +// } diff --git a/sha512/xor3.go b/sha512/xor3.go new file mode 100644 index 0000000..a187843 --- /dev/null +++ b/sha512/xor3.go @@ -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