From bbab6412877c2ad554c7862ca1b38fa2ba041d8a Mon Sep 17 00:00:00 2001 From: Jacob Jackson Date: Mon, 3 Oct 2022 23:24:18 +0000 Subject: [PATCH 01/11] sha scaffold --- cubic.go | 1 + sha512/ch.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 sha512/ch.go diff --git a/cubic.go b/cubic.go index b4def71..0e793b9 100644 --- a/cubic.go +++ b/cubic.go @@ -22,6 +22,7 @@ import ( "github.com/consensys/gnark/frontend/cs/r1cs" "github.com/consensys/gnark/backend/groth16" _ "gnark-ed25519/edwards_curve" + _ "gnark-ed25519/sha512" ) // Circuit defines a simple circuit diff --git a/sha512/ch.go b/sha512/ch.go new file mode 100644 index 0000000..fbfde20 --- /dev/null +++ b/sha512/ch.go @@ -0,0 +1,28 @@ +package sha512 + +import ( + "github.com/consensys/gnark/frontend" +) + +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) + for k := 0; k < n; k++ { + out[k] = api.Add(api.Mul(a[k], api.Sub(b[k], c[k])), c[k]); + } + return out +} + +// template Ch_t512(n) { +// signal input a[n]; +// signal input b[n]; +// signal input c[n]; +// signal output out[n]; + +// for (var k=0; k Date: Tue, 4 Oct 2022 00:21:10 +0000 Subject: [PATCH 02/11] 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 Date: Mon, 3 Oct 2022 17:25:44 -0700 Subject: [PATCH 03/11] Added first half of templates --- sha512/constants.go | 79 +++++++++++++++++++++++++++++++++++++++++++++ sha512/maj.go | 33 +++++++++++++++++++ sha512/rotate.go | 24 ++++++++++++++ sha512/sha512.go | 65 +++++++++++++++++++++++++++++++++++++ sha512/utils.go | 19 +++++++++++ 5 files changed, 220 insertions(+) create mode 100644 sha512/constants.go create mode 100644 sha512/maj.go create mode 100644 sha512/rotate.go create mode 100644 sha512/sha512.go create mode 100644 sha512/utils.go diff --git a/sha512/constants.go b/sha512/constants.go new file mode 100644 index 0000000..ac62dec --- /dev/null +++ b/sha512/constants.go @@ -0,0 +1,79 @@ +package sha512 + +import ( + "github.com/consensys/gnark/frontend" +) + +func H512(x uint) ([] frontend.Variable) { + out := make([] frontend.Variable, 64) + cInt := [8]uint{0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179} + for k := 0; k < 64; k++ { + out[k] = (cInt[x] >> k) & 1 + } + return out +} + +// template H512(x) { +// signal output out[64]; +// var c[8] = [ +// 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, +// 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179 +// ]; + +// for (var i=0; i<64; i++) { +// out[i] <== (c[x] >> i) & 1; +// } +// } + +func K512(x uint) ([] frontend.Variable) { + out := make([] frontend.Variable, 64) + c := [80]uint{ + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, + 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, + 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, + 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, + 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab, + 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, + 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, + 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, + 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, + 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, + 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, + 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c, + 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6, + 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, + 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817} + for k := 0; k < 64; k++ { + out[k] = (c[x] >> k) & 1 + } + return out +} + + +// template K512(x) { +// signal output out[64]; +// var c[80] = [ +// 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, +// 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, +// 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, +// 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, +// 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab, +// 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, +// 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, +// 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, +// 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, +// 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, +// 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, +// 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, +// 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c, +// 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6, +// 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, +// 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 +// ]; + +// for (var i=0; i<64; i++) { +// out[i] <== (c[x] >> i) & 1; +// } +// } \ No newline at end of file diff --git a/sha512/maj.go b/sha512/maj.go new file mode 100644 index 0000000..50dc073 --- /dev/null +++ b/sha512/maj.go @@ -0,0 +1,33 @@ +package sha512 + +import ( + "github.com/consensys/gnark/frontend" +) + +func Maj_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") } + mid := make([] frontend.Variable, n) + out := make([] frontend.Variable, n) + for k := 0; k < n; k++ { + mid[k] = api.Mul(b[k], c[k]) + out[k] = api.Add(api.Mul(a[k], api.Sub(api.Add(b[k], c[k]), api.Mul(2, mid[k]))), mid[k]) + } + return out +} + + +// template Maj_t512(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> k) & 1 + } + + var h512Components = [8][]frontend.Variable + + for i := 0; i < 8; i++ { + h512Components[i] = H512(i) + } + + sha512compression := make([][] frontend.Variable, nBlocks) + + for i := 0; i < nBlocks; i++ { + var hin = make([] frontend.Variable, 64 * 8) + var inp = make([] frontend.Variable, 1024) + if i == 0 { + for k := 0; k < 64; k++ { + for j := 0; j < 8; j++ { + hin[j*64 + k] = h512Components[j][k] + } + } + } else { + for k := 0; k < 64; k++ { + for j := 0; j < 8; j++ { + hin[j*64 + k] = sha512compression[i-1][64*j+63-k] + } + } + } + for k := 0; k < 1024; k++ { + inp[k] = paddedIn[i*1024 + k] + } + sha512compression[i] = Sha512Compression(api, hin, inp) + } + + var out = [512]frontend.Variable + + for k := 0; k < 512; k++ { + out[k] = sha512compression[nBlocks-1][k] + + } + + return out +} diff --git a/sha512/utils.go b/sha512/utils.go new file mode 100644 index 0000000..6661197 --- /dev/null +++ b/sha512/utils.go @@ -0,0 +1,19 @@ +package sha512 + +import ("math/big") + +func newBigInt(s string) *big.Int { + result, success := new(big.Int).SetString(s, 16) + if !success { + panic("invalid bigint") + } + return result +} + +func newBigIntBase10(s string) *big.Int { + result, success := new(big.Int).SetString(s, 10) + if !success { + panic("invalid bigint") + } + return result +} \ No newline at end of file From 8726a772bc98aa0147022ea8ae44e58ae0b2d6cc Mon Sep 17 00:00:00 2001 From: puma314 Date: Mon, 3 Oct 2022 17:55:11 -0700 Subject: [PATCH 04/11] Fixed compile errors --- sha512/constants.go | 4 ++-- sha512/sha512.go | 10 ++++----- sha512/sha512compression.go | 42 ++++++++++++++++++------------------- sha512/sigma.go | 16 +++++++------- sha512/sigmaplus.go | 8 +++---- sha512/t1.go | 6 +++--- sha512/t2.go | 6 +++--- sha512/xor3.go | 6 +++--- 8 files changed, 49 insertions(+), 49 deletions(-) diff --git a/sha512/constants.go b/sha512/constants.go index ac62dec..60af362 100644 --- a/sha512/constants.go +++ b/sha512/constants.go @@ -4,8 +4,8 @@ import ( "github.com/consensys/gnark/frontend" ) -func H512(x uint) ([] frontend.Variable) { - out := make([] frontend.Variable, 64) +func H512(x uint) ([64] frontend.Variable) { + var out [64]frontend.Variable cInt := [8]uint{0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179} for k := 0; k < 64; k++ { diff --git a/sha512/sha512.go b/sha512/sha512.go index f0a9b4c..e642cea 100644 --- a/sha512/sha512.go +++ b/sha512/sha512.go @@ -4,7 +4,7 @@ import ( "github.com/consensys/gnark/frontend" ) -func Sha512(api frontend.API, in [] frontend.Variable) ([] frontend.Variable) { +func Sha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variable) { nBits := len(in) nBlocks := ((nBits + 128) / 1024) + 1 @@ -24,10 +24,10 @@ func Sha512(api frontend.API, in [] frontend.Variable) ([] frontend.Variable) { paddedIn[nBlocks*1024 - k - 1] = (nBits >> k) & 1 } - var h512Components = [8][]frontend.Variable + var h512Components [8][64]frontend.Variable for i := 0; i < 8; i++ { - h512Components[i] = H512(i) + h512Components[i] = H512(uint(i)) } sha512compression := make([][] frontend.Variable, nBlocks) @@ -51,10 +51,10 @@ func Sha512(api frontend.API, in [] frontend.Variable) ([] frontend.Variable) { for k := 0; k < 1024; k++ { inp[k] = paddedIn[i*1024 + k] } - sha512compression[i] = Sha512Compression(api, hin, inp) + sha512compression[i] = Sha512compression(api, hin, inp) } - var out = [512]frontend.Variable + var out [512]frontend.Variable for k := 0; k < 512; k++ { out[k] = sha512compression[nBlocks-1][k] diff --git a/sha512/sha512compression.go b/sha512/sha512compression.go index d614623..fd5c4a2 100644 --- a/sha512/sha512compression.go +++ b/sha512/sha512compression.go @@ -11,7 +11,7 @@ func Sha512compression(api frontend.API, hin, inp []frontend.Variable) ([]fronte var ct_k [80][]frontend.Variable for i := 0; i < 80; i++ { - ct_k[i] = K512(i) + ct_k[i] = K512(uint(i)) } var a [81][64]frontend.Variable @@ -30,7 +30,7 @@ func Sha512compression(api frontend.API, hin, inp []frontend.Variable) ([]fronte w[t][k] = inp[t*64+63-k] } } else { - w[t] = SigmaPlus512(w[t-2], w[t-7], w[t-15], w[t-16]) + w[t] = SigmaPlus512(api, w[t-2][:], w[t-7][:], w[t-15][:], w[t-16][:]) } // if (t<16) { // for (k=0; k<64; k++) { @@ -73,8 +73,8 @@ func Sha512compression(api frontend.API, hin, inp []frontend.Variable) ([]fronte 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]) + t1 := T1_512(api, h[t][:], e[t][:], f[t][:], g[t][:], ct_k[t][:], w[t][:]) + t2 := T2_512(api, 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]; @@ -123,22 +123,22 @@ func Sha512compression(api frontend.API, hin, inp []frontend.Variable) ([]fronte 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] + fsum_in[0][0][k] = hin[64*0+k] + fsum_in[0][1][k] = a[80][k] + fsum_in[1][0][k] = hin[64*1+k] + fsum_in[1][1][k] = b[80][k] + fsum_in[2][0][k] = hin[64*2+k] + fsum_in[2][1][k] = c[80][k] + fsum_in[3][0][k] = hin[64*3+k] + fsum_in[3][1][k] = d[80][k] + fsum_in[4][0][k] = hin[64*4+k] + fsum_in[4][1][k] = e[80][k] + fsum_in[5][0][k] = hin[64*5+k] + fsum_in[5][1][k] = f[80][k] + fsum_in[6][0][k] = hin[64*6+k] + fsum_in[6][1][k] = g[80][k] + fsum_in[7][0][k] = hin[64*7+k] + fsum_in[7][1][k] = h[80][k] } // for (k=0; k<64; k++) { // fsum[0].in[0][k] <== hin[64*0+k]; @@ -186,5 +186,5 @@ func Sha512compression(api frontend.API, hin, inp []frontend.Variable) ([]fronte // out[384+63-k] <== fsum[6].out[k]; // out[448+63-k] <== fsum[7].out[k]; // } - return out + return out[:] } diff --git a/sha512/sigma.go b/sha512/sigma.go index 2e62eeb..30d9766 100644 --- a/sha512/sigma.go +++ b/sha512/sigma.go @@ -8,11 +8,11 @@ import ( 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) + rota := RotR512(api, in, ra) + rotb := RotR512(api, in, rb) + shrc := ShR512(api, in, rc) - return Xor3_512(rota, rotb, shrc) + return Xor3_512(api, rota, rotb, shrc) } // template SmallSigma512(ra, rb, rc) { @@ -45,11 +45,11 @@ func SmallSigma512(api frontend.API, in []frontend.Variable, ra, rb, rc int) ([] 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) + rota := RotR512(api, in, ra) + rotb := RotR512(api, in, rb) + rotc := RotR512(api, in, rc) - return Xor3_512(rota, rotb, rotc) + return Xor3_512(api, rota, rotb, rotc) } // template BigSigma512(ra, rb, rc) { diff --git a/sha512/sigmaplus.go b/sha512/sigmaplus.go index d2e4f5a..1daacac 100644 --- a/sha512/sigmaplus.go +++ b/sha512/sigmaplus.go @@ -5,13 +5,13 @@ import ( ) -func SigmaPlus512(api frontend.API, in2, in7, in15, in16 []frontend.Variable) ([]frontend.Variable) { +func SigmaPlus512(api frontend.API, in2, in7, in15, in16 []frontend.Variable) ([64]frontend.Variable) { if len(in2) != 64 { panic("bad length") } - sigma1 := SmallSigma512(in2, 19, 61, 6) - sigma0 := SmallSigma512(in15, 1, 8, 7) + sigma1 := SmallSigma512(api, in2, 19, 61, 6) + sigma0 := SmallSigma512(api, in15, 1, 8, 7) - return BinSum(sigma1, in7, sigma0, in16) + return BinSum(api, sigma1, in7, sigma0, in16) } diff --git a/sha512/t1.go b/sha512/t1.go index 69e3de6..7234557 100644 --- a/sha512/t1.go +++ b/sha512/t1.go @@ -13,10 +13,10 @@ func T1_512(api frontend.API, h, e, f, g, k, w []frontend.Variable) ([]frontend. 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) + ch := Ch_t512(api, e, f, g) + bigsigma1 := BigSigma512(api, e, 14, 18, 41) - return BinSum(h, bigsigma1, ch, k, w) + return BinSum(api, h, bigsigma1, ch, k, w) } // template T1_512() { diff --git a/sha512/t2.go b/sha512/t2.go index 52e225a..586d625 100644 --- a/sha512/t2.go +++ b/sha512/t2.go @@ -10,10 +10,10 @@ func T2_512(api frontend.API, a, b, c []frontend.Variable) ([]frontend.Variable) 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) + bigsigma0 := BigSigma512(api, a, 28, 34, 39) + maj := Maj_t512(api, a, b, c) - return BinSum(maj, bigsigma0) + return BinSum(api, maj, bigsigma0) } // template T2_512() { diff --git a/sha512/xor3.go b/sha512/xor3.go index a187843..599052a 100644 --- a/sha512/xor3.go +++ b/sha512/xor3.go @@ -12,9 +12,9 @@ func Xor3_512(api frontend.API, a, b, c []frontend.Variable) ([]frontend.Variabl 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])) + p := api.Add(1, api.Mul(-2, b[k]), api.Mul(-2, c[k]), api.Mul(4, mid)) + q := api.Mul(a[k], p) + out[k] = api.Add(q, b[k], c[k], api.Mul(-2, mid)) // TODO: try doing this instead: // out[k] = api.Xor(a[k], api.Xor(b[k], c[k])) } From 4fe5acca1ca2c3b6ecad31034ca7d10bf662cad4 Mon Sep 17 00:00:00 2001 From: Jacob Jackson Date: Tue, 4 Oct 2022 02:30:34 +0000 Subject: [PATCH 05/11] write binsum --- sha512/binsum.go | 135 ++++++++++++++++++++++++++++++++++++++++++ sha512/binsum_test.go | 52 ++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 sha512/binsum.go create mode 100644 sha512/binsum_test.go diff --git a/sha512/binsum.go b/sha512/binsum.go new file mode 100644 index 0000000..029761e --- /dev/null +++ b/sha512/binsum.go @@ -0,0 +1,135 @@ +package sha512 + +import ( + "fmt" + "math/big" + "github.com/consensys/gnark/backend/hint" + "github.com/consensys/gnark/frontend" +) + + +func padToSameLength(args [][]frontend.Variable) ([][]frontend.Variable, int) { + maxLength := 0 + for _, v := range args { + if len(v) > maxLength { + maxLength = len(v) + } + } + result := make([][]frontend.Variable, len(args)) + for i := 0; i < len(args); i++ { + if len(args[i]) < maxLength { + arr := make([]frontend.Variable, maxLength) + for j := 0; j < maxLength; j++ { + if j < len(args[i]) { + arr[j] = args[i][j] + } else { + arr[j] = 0 + } + } + result[i] = arr + } else { + result[i] = args[i] + } + } + return result, maxLength +} + +func log2(n int) int { + if n <= 0 { panic("undefined") } + result := 0 + n -= 1 + for n > 0 { + n >>= 1 + result += 1 + } + return result +} + +func extractBit(n big.Int) bool { + if !n.IsInt64() { + panic("not bit") + } + val := n.Int64() + if val == 0 { + return false + } else if val == 1 { + return true + } else { + panic("not bit") + } +} + +func flatten(arr [][]frontend.Variable) ([]frontend.Variable) { + totalLength := 0 + for _, v := range arr { + totalLength += len(v) + } + result := make([]frontend.Variable, totalLength) + i := 0 + for _, v := range arr { + for _, u := range v { + result[i] = u + i += 1 + } + } + return result +} + +func BinSum(api frontend.API, args ...[]frontend.Variable) ([]frontend.Variable) { + ops := len(args) + in, n := padToSameLength(args) + nout := n + log2(ops) +// var nout = nbits((2**n -1)*ops); +// signal input in[ops][n]; +// signal output out[nout]; + + var hintFn hint.Function = func(field *big.Int, inputs []*big.Int, outputs []*big.Int) error { + if len(inputs) != ops*n { panic("bad length") } + if len(outputs) != nout { panic("bad length") } + + maxOutputValue := big.NewInt(1) + maxOutputValue.Lsh(maxOutputValue, uint(nout)) + if maxOutputValue.Cmp(field) != -1 { panic("overflow") } + + result := big.NewInt(0) + for i := 0; i < ops; i++ { + placeValue := big.NewInt(1) + for j := 0; j < n; j++ { + if extractBit(*inputs[i*n+j]) { + result.Add(result, placeValue) + } + placeValue.Add(placeValue, placeValue) + } + } + for i := 0; i < nout; i++ { + v := new(big.Int).Rsh(result, uint(i)) + v.And(v, big.NewInt(1)) + outputs[i] = v + } + fmt.Println(ops, n, nout, inputs, outputs) + return nil + } + + out, err := api.NewHint(hintFn, nout, flatten(in)...) + if err != nil { + panic(err) + } + + var lhs frontend.Variable = 0 + var rhs frontend.Variable = 0 + + placeValue := big.NewInt(1) + for i := 0; i < nout; i++ { + for j := 0; j < ops; j++ { + if i < n { + lhs = api.Add(lhs, api.Mul(placeValue, in[j][i])) + } + } + rhs = api.Add(rhs, api.Mul(placeValue, out[i])) + api.AssertIsBoolean(out[i]) + placeValue.Add(placeValue, placeValue) + } + api.AssertIsEqual(lhs, rhs) + + return out +} diff --git a/sha512/binsum_test.go b/sha512/binsum_test.go new file mode 100644 index 0000000..2389c1b --- /dev/null +++ b/sha512/binsum_test.go @@ -0,0 +1,52 @@ +package sha512 + +import ( + "testing" + "fmt" + + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/test" + // "github.com/ethereum/go-ethereum/crypto/secp256k1" +) + +type BinsumTest struct { + A []frontend.Variable + B []frontend.Variable + C []frontend.Variable +} + +func (c *BinsumTest) Define(api frontend.API) error { + sum := BinSum(api, c.A, c.B) + for i := 0; i < len(sum) || i < len(c.C); i++ { + fmt.Println(i, c.C) + if i < len(sum) && i < len(c.C) { + api.Println(sum[i]) + api.AssertIsEqual(sum[i], c.C[i]) + } else if i < len(sum) { + api.AssertIsEqual(sum[i], 0) + } else { + fmt.Println(i, c.C[i]) + api.AssertIsEqual(c.C[i], 0) + } + } + return nil +} + +func TestBinsum(t *testing.T) { + assert := test.NewAssert(t) + circuit := BinsumTest{ + A: []frontend.Variable{0, 0, 0}, + B: []frontend.Variable{0, 0, 0}, + C: []frontend.Variable{0, 0, 0, 0}, + } + witness := BinsumTest{ + A: []frontend.Variable{1, 0, 1}, + B: []frontend.Variable{1, 1, 1}, + C: []frontend.Variable{0, 0, 1, 1}, + } + err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) + assert.NoError(err) +} + +var testCurve = ecc.BN254 From f7d1968b22ebd6565f8970b99e26640a72343c50 Mon Sep 17 00:00:00 2001 From: puma314 Date: Mon, 3 Oct 2022 21:56:27 -0700 Subject: [PATCH 06/11] Compiles --- sha512/sha512compression.go | 6 +++--- sha512/sha_test.go | 37 +++++++++++++++++++++++++++++++++++++ sha512/sigmaplus.go | 7 ++++++- 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 sha512/sha_test.go diff --git a/sha512/sha512compression.go b/sha512/sha512compression.go index fd5c4a2..af3465b 100644 --- a/sha512/sha512compression.go +++ b/sha512/sha512compression.go @@ -88,8 +88,8 @@ func Sha512compression(api frontend.API, hin, inp []frontend.Variable) ([]fronte // t2[t].c[k] <== c[t][k]; // } - sume := BinSum(d[t], t1) - suma := BinSum(t1, t2) + sume := BinSum(api, d[t][:], t1) + suma := BinSum(api, 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]; @@ -161,7 +161,7 @@ func Sha512compression(api frontend.API, hin, inp []frontend.Variable) ([]fronte var fsum [8][]frontend.Variable for i := 0; i < 8; i++ { - fsum[i] = BinSum(fsum_in[i][0], fsum_in[i][1]) + fsum[i] = BinSum(api, fsum_in[i][0][:], fsum_in[i][1][:]) } var out [512]frontend.Variable diff --git a/sha512/sha_test.go b/sha512/sha_test.go new file mode 100644 index 0000000..fe567fb --- /dev/null +++ b/sha512/sha_test.go @@ -0,0 +1,37 @@ +package sha512 + +import ( + "math/big" + "testing" + + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/test" +) + +type Sha512Circuit struct { + in []frontend.Variable `gnark:"in"` + out []frontend.Variable `gnark:"out"` +} + +func (circuit *Sha512Circuit) Define(api frontend.API) error { + res := Sha512(api, circuit.in) + for i := 0; i < 512; i++ { + api.AssertIsEqual(res[i], circuit.out[i]) + } + return nil +} + +func TestSha512(t *testing.T) { + assert := test.NewAssert(t) + circuit := OnCurveTest[Ed25519, Ed25519Scalars]{} + witness := OnCurveTest[Ed25519, Ed25519Scalars]{ + P: AffinePoint[Ed25519]{ + X: emulated.NewElement[Ed25519](newBigInt("216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A")), + Y: emulated.NewElement[Ed25519](newBigInt("6666666666666666666666666666666666666666666666666666666666666658")), + }, + } + err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) + assert.NoError(err) +} + +var testCurve = ecc.BN254 diff --git a/sha512/sigmaplus.go b/sha512/sigmaplus.go index 1daacac..4ac5a78 100644 --- a/sha512/sigmaplus.go +++ b/sha512/sigmaplus.go @@ -11,7 +11,12 @@ func SigmaPlus512(api frontend.API, in2, in7, in15, in16 []frontend.Variable) ([ sigma1 := SmallSigma512(api, in2, 19, 61, 6) sigma0 := SmallSigma512(api, in15, 1, 8, 7) - return BinSum(api, sigma1, in7, sigma0, in16) + inter := BinSum(api, sigma1, in7, sigma0, in16) + var out [64]frontend.Variable + for k := 0; k < 64; k++ { + out[k] = inter[k] + } + return out } From 5bb4de69bba94202fcbd6010f41cdcc7ff839732 Mon Sep 17 00:00:00 2001 From: Jacob Jackson Date: Tue, 4 Oct 2022 17:16:50 +0000 Subject: [PATCH 07/11] get test running --- sha512/binsum.go | 2 -- sha512/sha_test.go | 28 ++++++++++++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/sha512/binsum.go b/sha512/binsum.go index 029761e..3c4ef60 100644 --- a/sha512/binsum.go +++ b/sha512/binsum.go @@ -1,7 +1,6 @@ package sha512 import ( - "fmt" "math/big" "github.com/consensys/gnark/backend/hint" "github.com/consensys/gnark/frontend" @@ -106,7 +105,6 @@ func BinSum(api frontend.API, args ...[]frontend.Variable) ([]frontend.Variable) v.And(v, big.NewInt(1)) outputs[i] = v } - fmt.Println(ops, n, nout, inputs, outputs) return nil } diff --git a/sha512/sha_test.go b/sha512/sha_test.go index fe567fb..78a142d 100644 --- a/sha512/sha_test.go +++ b/sha512/sha_test.go @@ -1,7 +1,6 @@ package sha512 import ( - "math/big" "testing" "github.com/consensys/gnark/frontend" @@ -23,15 +22,28 @@ func (circuit *Sha512Circuit) Define(api frontend.API) error { func TestSha512(t *testing.T) { assert := test.NewAssert(t) - circuit := OnCurveTest[Ed25519, Ed25519Scalars]{} - witness := OnCurveTest[Ed25519, Ed25519Scalars]{ - P: AffinePoint[Ed25519]{ - X: emulated.NewElement[Ed25519](newBigInt("216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A")), - Y: emulated.NewElement[Ed25519](newBigInt("6666666666666666666666666666666666666666666666666666666666666658")), - }, + in := toBytes("Succinct Labs") + out := toBytes("503ace098aa03f6feec1b5df0a38aee923f744a775508bc81f2b94ad139be297c2e8cd8c44af527b5d3f017a7fc929892c896604047e52e3f518924f52bff0dc") + circuit := Sha512Circuit { + in: toVariables(make([]byte, len(in))), + out: toVariables(make([]byte, len(out))), + } + witness := Sha512Circuit { + in: toVariables(in), + out: toVariables(out), } err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) assert.NoError(err) } -var testCurve = ecc.BN254 +func toVariables(arr []byte) []frontend.Variable { + result := make([]frontend.Variable, len(arr)) + for i, v := range arr { + result[i] = v + } + return result +} + +func toBytes(s string) []byte { + return []byte(s) +} From d4401cf94bdcae3f827fb74de8e6179d7a3f9a3a Mon Sep 17 00:00:00 2001 From: Jacob Jackson Date: Tue, 4 Oct 2022 19:40:00 +0000 Subject: [PATCH 08/11] port python implementation --- sha512/binsum_test.go | 4 - sha512/pysha512.go | 367 ++++++++++++++++++++++++++++++++++++++++++ sha512/sha512.go | 7 + sha512/sha_test.go | 47 ++++-- 4 files changed, 406 insertions(+), 19 deletions(-) create mode 100644 sha512/pysha512.go diff --git a/sha512/binsum_test.go b/sha512/binsum_test.go index 2389c1b..a799e10 100644 --- a/sha512/binsum_test.go +++ b/sha512/binsum_test.go @@ -2,7 +2,6 @@ package sha512 import ( "testing" - "fmt" "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/frontend" @@ -19,14 +18,11 @@ type BinsumTest struct { func (c *BinsumTest) Define(api frontend.API) error { sum := BinSum(api, c.A, c.B) for i := 0; i < len(sum) || i < len(c.C); i++ { - fmt.Println(i, c.C) if i < len(sum) && i < len(c.C) { - api.Println(sum[i]) api.AssertIsEqual(sum[i], c.C[i]) } else if i < len(sum) { api.AssertIsEqual(sum[i], 0) } else { - fmt.Println(i, c.C[i]) api.AssertIsEqual(c.C[i], 0) } } diff --git a/sha512/pysha512.go b/sha512/pysha512.go new file mode 100644 index 0000000..bed5dec --- /dev/null +++ b/sha512/pysha512.go @@ -0,0 +1,367 @@ +package sha512 + +import ( + "github.com/consensys/gnark/frontend" +) + + +func _right_rotate(n [64]frontend.Variable, bits int) [64]frontend.Variable { + var result [64]frontend.Variable + for i := 0; i < len(n); i++ { + result[(i+bits)%len(n)] = n[i] + } + 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) { + _not := func(x [64]frontend.Variable) [64]frontend.Variable { + return not(api, x) + } + _and := func(xs ...[64]frontend.Variable) [64]frontend.Variable { + return and(api, xs...) + } + _add := func(xs ...[64]frontend.Variable) [64]frontend.Variable { + return add(api, xs...) + } + _xor := func(xs ...[64]frontend.Variable) [64]frontend.Variable { + return xor(api, xs...) + } + zip_add := func(a, b Array8_64) Array8_64 { + a0, a1, a2, a3, a4, a5, a6, a7 := unpack8(a) + b0, b1, b2, b3, b4, b5, b6, b7 := unpack8(b) + return Array8_64{ + _add(a0, b0), + _add(a1, b1), + _add(a2, b2), + _add(a3, b3), + _add(a4, b4), + _add(a5, b5), + _add(a6, b6), + _add(a7, b7), + } + } + initial_hash := []uint64{ + 0x6a09e667f3bcc908, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, + } + round_constants := []uint64{ + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, + 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, + 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, + 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, + 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, + 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275, + 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, + 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, + 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, + 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, + 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, + 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, + 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001, + 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, + 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, + 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, + 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, + 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, + 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207, + 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, + 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, + 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, + 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, + 0x5fcb6fab3ad6faec, 0x6c44198c4a475817, + } + for _, v := range in { + api.AssertIsBoolean(v) + } + mdi := divChecked(len(in), 8) % 128 +// mdi = len(message_array) % 128 + var padding_len int + if mdi < 112 { + padding_len = 119 - mdi + } else { + padding_len = 247 - mdi + } +// padding_len = 119 - mdi if mdi < 112 else 247 - mdi + message_length_bits := uint64ToBits(uint64(len(in))) +// ending = struct.pack('!Q', len(message_array) << 3) + in = append(in, 1) + for i := 0; i < 7; i++ { + in = append(in, 0) + } +// message_array.append(0x80) + for i := 0; i < padding_len * 8; i++ { + in = append(in, 0) + } +// message_array.extend([0] * padding_len) + for i := 0; i < 64; i++ { + in = append(in, message_length_bits[i]) + } +// message_array.extend(bytearray(ending)) + + sha512_hash := Array8_64{ + uint64ToBits(initial_hash[0]), + uint64ToBits(initial_hash[1]), + uint64ToBits(initial_hash[2]), + uint64ToBits(initial_hash[3]), + uint64ToBits(initial_hash[4]), + uint64ToBits(initial_hash[5]), + uint64ToBits(initial_hash[6]), + 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 in range(0, len(message_array), 128): + chunk := in[chunk_start * 8 : (chunk_start+128) * 8] +// chunk = message_array[chunk_start:chunk_start + 128] + if len(chunk) != 1024 { panic("bad length") } + u := make([]frontend.Variable, 80 * 64) + for i, _ := range u { + u[i] = 0 + } +// w = [0] * 80 + copy(u, chunk) +// w[0:16] = struct.unpack('!16Q', chunk) + + w := reshape(u) + + for i := 16; i < 80; i++ { +// for i in range(16, 80): + s0 := _xor( + _right_rotate(w[i - 15], 1), + _right_rotate(w[i - 15], 8), + _shr(w[i - 15], 7), + ) +// s0 = ( +// _right_rotate(w[i - 15], 1) ^ +// _right_rotate(w[i - 15], 8) ^ +// (w[i - 15] >> 7) +// ) + s1 := _xor( + _right_rotate(w[i - 2], 19), + _right_rotate(w[i - 2], 61), + _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] = (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 = sha512_hash + for i := 0; i < 80; i++ { +// for i in range(80): + + sum1 := _xor( + _right_rotate(e, 14), + _right_rotate(e, 18), + _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 = (e & f) ^ (~e & g) + temp1 := _add(h, sum1, ch, uint64ToBits(round_constants[i]), w[i]) +// temp1 = h + sum1 + ch + round_constants[i] + w[i] + sum0 := _xor( + _right_rotate(a, 28), + _right_rotate(a, 34), + _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 = (a & b) ^ (a & c) ^ (b & c) + temp2 := _add(sum0, maj) +// temp2 = sum0 + maj + + h = g + g = f + f = e + e = _add(d, temp1) + d = c + c = b + b = a + 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}) + } + 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 { + l := divChecked(len(u), 64) + result := make([][64]frontend.Variable, l) + for i := 0; i < l; i++ { + var arr [64]frontend.Variable + for k := 0; k < 64; k++ { + arr[k] = u[i*64+k] + } + result[i] = arr + } + return result +} + +type Array8_64 [8][64]frontend.Variable + +func unpack8(x Array8_64) ([64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable) { + return x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7] +} + +func flatten8(x Array8_64) [512]frontend.Variable { + var result [512]frontend.Variable + k := 0 + for i := 0; i < 8; i++ { + for j := 0; j < 64; j++ { + result[k] = x[i][j] + k++ + } + } + return result +} + +func uint64ToBits(value uint64) [64]frontend.Variable { + var result [64]frontend.Variable + for k := 0; k < 64; k++ { + if (value & (1 << (63-k))) != 0 { + result[k] = 1 + } else { + result[k] = 0 + } + } + return result +} + +func xor(api frontend.API, args ...[64]frontend.Variable) [64]frontend.Variable { + if len(args) == 1 { + return args[0] + } else { + return xor2(api, args[0], xor(api, args[1:]...)) + } +} +func add(api frontend.API, args ...[64]frontend.Variable) [64]frontend.Variable { + if len(args) == 1 { + return args[0] + } else { + return add2(api, args[0], add(api, args[1:]...)) + } +} +func and(api frontend.API, args ...[64]frontend.Variable) [64]frontend.Variable { + if len(args) == 1 { + return args[0] + } else { + return and2(api, args[0], and(api, args[1:]...)) + } +} + +func xor2(api frontend.API, a, b [64]frontend.Variable) [64]frontend.Variable { + var result [64]frontend.Variable + for i := 0; i < 64; i++ { + result[i] = api.Xor(a[i], b[i]) + } + return result +} + +func and2(api frontend.API, a, b [64]frontend.Variable) [64]frontend.Variable { + var result [64]frontend.Variable + for i := 0; i < 64; i++ { + result[i] = api.And(a[i], b[i]) + } + return result +} + +func add2(api frontend.API, a, b [64]frontend.Variable) [64]frontend.Variable { + var result [64]frontend.Variable + var carry frontend.Variable = 0 + for i := 63; i >= 0; i-- { + sum := api.Add(a[i], b[i], carry) + sumBin := api.ToBinary(sum, 2) + if len(sumBin) != 2 { + panic("bad length") + } + result[i] = sumBin[0] + carry = sumBin[1] + } + return result +} + +func _shr(n [64]frontend.Variable, bits int) [64]frontend.Variable { + var result [64]frontend.Variable + for i := 0; i < 64; i++ { + if i < bits { + result[i] = 0 + } else { + result[i] = n[i - bits] + } + } + return result +} + +func not(api frontend.API, n [64]frontend.Variable) [64]frontend.Variable { + var result [64]frontend.Variable + for i := 0; i < 64; i++ { + result[i] = api.Sub(1, n[i]) + } + return result +} + +func divChecked(a, b int) int { + if a % b != 0 { + panic("divChecked: does not divide evenly") + } + return a / b +} + diff --git a/sha512/sha512.go b/sha512/sha512.go index e642cea..76fbb6c 100644 --- a/sha512/sha512.go +++ b/sha512/sha512.go @@ -1,12 +1,17 @@ package sha512 import ( + "fmt" "github.com/consensys/gnark/frontend" ) func Sha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variable) { nBits := len(in) + for _, v := range in { + api.AssertIsBoolean(v) + } + nBlocks := ((nBits + 128) / 1024) + 1 paddedIn := make([] frontend.Variable, nBlocks * 1024) @@ -24,6 +29,8 @@ func Sha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variable) paddedIn[nBlocks*1024 - k - 1] = (nBits >> k) & 1 } + fmt.Println(paddedIn) + var h512Components [8][64]frontend.Variable for i := 0; i < 8; i++ { diff --git a/sha512/sha_test.go b/sha512/sha_test.go index 78a142d..8b41fbb 100644 --- a/sha512/sha_test.go +++ b/sha512/sha_test.go @@ -2,6 +2,7 @@ package sha512 import ( "testing" + "encoding/hex" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/test" @@ -13,7 +14,8 @@ type Sha512Circuit struct { } func (circuit *Sha512Circuit) Define(api frontend.API) error { - res := Sha512(api, circuit.in) + res := PySha512(api, circuit.in) + if len(res) != 512 { panic("bad length") } for i := 0; i < 512; i++ { api.AssertIsEqual(res[i], circuit.out[i]) } @@ -22,24 +24,39 @@ func (circuit *Sha512Circuit) Define(api frontend.API) error { func TestSha512(t *testing.T) { assert := test.NewAssert(t) - in := toBytes("Succinct Labs") - out := toBytes("503ace098aa03f6feec1b5df0a38aee923f744a775508bc81f2b94ad139be297c2e8cd8c44af527b5d3f017a7fc929892c896604047e52e3f518924f52bff0dc") - circuit := Sha512Circuit { - in: toVariables(make([]byte, len(in))), - out: toVariables(make([]byte, len(out))), - } - witness := Sha512Circuit { - in: toVariables(in), - out: toVariables(out), + + testCase := func(input, output string) { + in := toBytes(input) + out, err := hex.DecodeString(output) + if err != nil { panic(err) } + if len(out) != 512 / 8 { panic("bad output length") } + + circuit := Sha512Circuit { + in: toBits(in), + out: toBits(out), + } + witness := Sha512Circuit { + in: toBits(in), + out: toBits(out), + } + err = test.IsSolved(&circuit, &witness, testCurve.ScalarField()) + assert.NoError(err) } - err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) - assert.NoError(err) + + testCase("", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e") + testCase("Succinct Labs", "503ace098aa03f6feec1b5df0a38aee923f744a775508bc81f2b94ad139be297c2e8cd8c44af527b5d3f017a7fc929892c896604047e52e3f518924f52bff0dc") } -func toVariables(arr []byte) []frontend.Variable { - result := make([]frontend.Variable, len(arr)) +func toBits(arr []byte) []frontend.Variable { + result := make([]frontend.Variable, len(arr) * 8) for i, v := range arr { - result[i] = v + for j := 0; j < 8; j++ { + if (v & (1 << (7-j))) != 0 { + result[i*8+j] = 1 + } else { + result[i*8+j] = 0 + } + } } return result } From 105839d5bf44d09459fbeee813c9eef4d675cb0f Mon Sep 17 00:00:00 2001 From: Jacob Jackson Date: Tue, 4 Oct 2022 19:41:26 +0000 Subject: [PATCH 09/11] remove comments from original python --- sha512/pysha512.go | 78 ++-------------------------------------------- 1 file changed, 2 insertions(+), 76 deletions(-) diff --git a/sha512/pysha512.go b/sha512/pysha512.go index bed5dec..d4c8818 100644 --- a/sha512/pysha512.go +++ b/sha512/pysha512.go @@ -1,5 +1,7 @@ package sha512 +// Based on https://gist.github.com/illia-v/7883be942da5d416521375004cecb68f + import ( "github.com/consensys/gnark/frontend" ) @@ -12,8 +14,6 @@ func _right_rotate(n [64]frontend.Variable, bits int) [64]frontend.Variable { } 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) { _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) } mdi := divChecked(len(in), 8) % 128 -// mdi = len(message_array) % 128 var padding_len int if mdi < 112 { padding_len = 119 - mdi } else { padding_len = 247 - mdi } -// padding_len = 119 - mdi if mdi < 112 else 247 - mdi message_length_bits := uint64ToBits(uint64(len(in))) -// ending = struct.pack('!Q', len(message_array) << 3) in = append(in, 1) for i := 0; i < 7; i++ { in = append(in, 0) } -// message_array.append(0x80) for i := 0; i < padding_len * 8; i++ { in = append(in, 0) } -// message_array.extend([0] * padding_len) for i := 0; i < 64; i++ { in = append(in, message_length_bits[i]) } -// message_array.extend(bytearray(ending)) sha512_hash := Array8_64{ 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[7]), } -// sha512_hash = list(initial_hash) 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 = message_array[chunk_start:chunk_start + 128] if len(chunk) != 1024 { panic("bad length") } u := make([]frontend.Variable, 80 * 64) for i, _ := range u { u[i] = 0 } -// w = [0] * 80 copy(u, chunk) -// w[0:16] = struct.unpack('!16Q', chunk) w := reshape(u) for i := 16; i < 80; i++ { -// for i in range(16, 80): s0 := _xor( _right_rotate(w[i - 15], 1), _right_rotate(w[i - 15], 8), _shr(w[i - 15], 7), ) -// s0 = ( -// _right_rotate(w[i - 15], 1) ^ -// _right_rotate(w[i - 15], 8) ^ -// (w[i - 15] >> 7) -// ) s1 := _xor( _right_rotate(w[i - 2], 19), _right_rotate(w[i - 2], 61), _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] = (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 = sha512_hash for i := 0; i < 80; i++ { -// for i in range(80): - sum1 := _xor( _right_rotate(e, 14), _right_rotate(e, 18), _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 = (e & f) ^ (~e & g) temp1 := _add(h, sum1, ch, uint64ToBits(round_constants[i]), w[i]) -// temp1 = h + sum1 + ch + round_constants[i] + w[i] sum0 := _xor( _right_rotate(a, 28), _right_rotate(a, 34), _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 = (a & b) ^ (a & c) ^ (b & c) temp2 := _add(sum0, maj) -// temp2 = sum0 + maj h = g g = f @@ -202,46 +162,12 @@ func PySha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variabl c = b b = a 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}) } 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 { l := divChecked(len(u), 64) result := make([][64]frontend.Variable, l) From 61568028c3016a2f5cf6e0e63cb691dc9e36114b Mon Sep 17 00:00:00 2001 From: Jacob Jackson Date: Tue, 4 Oct 2022 19:42:42 +0000 Subject: [PATCH 10/11] remove old code --- sha512/binsum.go | 133 ------------------------- sha512/binsum_test.go | 48 --------- sha512/ch.go | 28 ------ sha512/constants.go | 79 --------------- sha512/maj.go | 33 ------- sha512/rotate.go | 24 ----- sha512/sha512.go | 72 -------------- sha512/sha512compression.go | 190 ------------------------------------ sha512/sha_test.go | 3 + sha512/shift.go | 32 ------ sha512/sigma.go | 81 --------------- sha512/sigmaplus.go | 49 ---------- sha512/t1.go | 55 ----------- sha512/t2.go | 45 --------- sha512/utils.go | 19 ---- sha512/xor3.go | 35 ------- 16 files changed, 3 insertions(+), 923 deletions(-) delete mode 100644 sha512/binsum.go delete mode 100644 sha512/binsum_test.go delete mode 100644 sha512/ch.go delete mode 100644 sha512/constants.go delete mode 100644 sha512/maj.go delete mode 100644 sha512/rotate.go delete mode 100644 sha512/sha512.go delete mode 100644 sha512/sha512compression.go delete mode 100644 sha512/shift.go delete mode 100644 sha512/sigma.go delete mode 100644 sha512/sigmaplus.go delete mode 100644 sha512/t1.go delete mode 100644 sha512/t2.go delete mode 100644 sha512/utils.go delete mode 100644 sha512/xor3.go diff --git a/sha512/binsum.go b/sha512/binsum.go deleted file mode 100644 index 3c4ef60..0000000 --- a/sha512/binsum.go +++ /dev/null @@ -1,133 +0,0 @@ -package sha512 - -import ( - "math/big" - "github.com/consensys/gnark/backend/hint" - "github.com/consensys/gnark/frontend" -) - - -func padToSameLength(args [][]frontend.Variable) ([][]frontend.Variable, int) { - maxLength := 0 - for _, v := range args { - if len(v) > maxLength { - maxLength = len(v) - } - } - result := make([][]frontend.Variable, len(args)) - for i := 0; i < len(args); i++ { - if len(args[i]) < maxLength { - arr := make([]frontend.Variable, maxLength) - for j := 0; j < maxLength; j++ { - if j < len(args[i]) { - arr[j] = args[i][j] - } else { - arr[j] = 0 - } - } - result[i] = arr - } else { - result[i] = args[i] - } - } - return result, maxLength -} - -func log2(n int) int { - if n <= 0 { panic("undefined") } - result := 0 - n -= 1 - for n > 0 { - n >>= 1 - result += 1 - } - return result -} - -func extractBit(n big.Int) bool { - if !n.IsInt64() { - panic("not bit") - } - val := n.Int64() - if val == 0 { - return false - } else if val == 1 { - return true - } else { - panic("not bit") - } -} - -func flatten(arr [][]frontend.Variable) ([]frontend.Variable) { - totalLength := 0 - for _, v := range arr { - totalLength += len(v) - } - result := make([]frontend.Variable, totalLength) - i := 0 - for _, v := range arr { - for _, u := range v { - result[i] = u - i += 1 - } - } - return result -} - -func BinSum(api frontend.API, args ...[]frontend.Variable) ([]frontend.Variable) { - ops := len(args) - in, n := padToSameLength(args) - nout := n + log2(ops) -// var nout = nbits((2**n -1)*ops); -// signal input in[ops][n]; -// signal output out[nout]; - - var hintFn hint.Function = func(field *big.Int, inputs []*big.Int, outputs []*big.Int) error { - if len(inputs) != ops*n { panic("bad length") } - if len(outputs) != nout { panic("bad length") } - - maxOutputValue := big.NewInt(1) - maxOutputValue.Lsh(maxOutputValue, uint(nout)) - if maxOutputValue.Cmp(field) != -1 { panic("overflow") } - - result := big.NewInt(0) - for i := 0; i < ops; i++ { - placeValue := big.NewInt(1) - for j := 0; j < n; j++ { - if extractBit(*inputs[i*n+j]) { - result.Add(result, placeValue) - } - placeValue.Add(placeValue, placeValue) - } - } - for i := 0; i < nout; i++ { - v := new(big.Int).Rsh(result, uint(i)) - v.And(v, big.NewInt(1)) - outputs[i] = v - } - return nil - } - - out, err := api.NewHint(hintFn, nout, flatten(in)...) - if err != nil { - panic(err) - } - - var lhs frontend.Variable = 0 - var rhs frontend.Variable = 0 - - placeValue := big.NewInt(1) - for i := 0; i < nout; i++ { - for j := 0; j < ops; j++ { - if i < n { - lhs = api.Add(lhs, api.Mul(placeValue, in[j][i])) - } - } - rhs = api.Add(rhs, api.Mul(placeValue, out[i])) - api.AssertIsBoolean(out[i]) - placeValue.Add(placeValue, placeValue) - } - api.AssertIsEqual(lhs, rhs) - - return out -} diff --git a/sha512/binsum_test.go b/sha512/binsum_test.go deleted file mode 100644 index a799e10..0000000 --- a/sha512/binsum_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package sha512 - -import ( - "testing" - - "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/test" - // "github.com/ethereum/go-ethereum/crypto/secp256k1" -) - -type BinsumTest struct { - A []frontend.Variable - B []frontend.Variable - C []frontend.Variable -} - -func (c *BinsumTest) Define(api frontend.API) error { - sum := BinSum(api, c.A, c.B) - for i := 0; i < len(sum) || i < len(c.C); i++ { - if i < len(sum) && i < len(c.C) { - api.AssertIsEqual(sum[i], c.C[i]) - } else if i < len(sum) { - api.AssertIsEqual(sum[i], 0) - } else { - api.AssertIsEqual(c.C[i], 0) - } - } - return nil -} - -func TestBinsum(t *testing.T) { - assert := test.NewAssert(t) - circuit := BinsumTest{ - A: []frontend.Variable{0, 0, 0}, - B: []frontend.Variable{0, 0, 0}, - C: []frontend.Variable{0, 0, 0, 0}, - } - witness := BinsumTest{ - A: []frontend.Variable{1, 0, 1}, - B: []frontend.Variable{1, 1, 1}, - C: []frontend.Variable{0, 0, 1, 1}, - } - err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) - assert.NoError(err) -} - -var testCurve = ecc.BN254 diff --git a/sha512/ch.go b/sha512/ch.go deleted file mode 100644 index b295dcd..0000000 --- a/sha512/ch.go +++ /dev/null @@ -1,28 +0,0 @@ -package sha512 - -import ( - "github.com/consensys/gnark/frontend" -) - -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) - for k := 0; k < n; k++ { - out[k] = api.Add(api.Mul(a[k], api.Sub(b[k], c[k])), c[k]); - } - return out -} - -// template Ch_t512(n) { -// signal input a[n]; -// signal input b[n]; -// signal input c[n]; -// signal output out[n]; - -// for (var k=0; k> k) & 1 - } - return out -} - -// template H512(x) { -// signal output out[64]; -// var c[8] = [ -// 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, -// 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179 -// ]; - -// for (var i=0; i<64; i++) { -// out[i] <== (c[x] >> i) & 1; -// } -// } - -func K512(x uint) ([] frontend.Variable) { - out := make([] frontend.Variable, 64) - c := [80]uint{ - 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, - 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, - 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, - 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, - 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab, - 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, - 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, - 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, - 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, - 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, - 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, - 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, - 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c, - 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6, - 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, - 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817} - for k := 0; k < 64; k++ { - out[k] = (c[x] >> k) & 1 - } - return out -} - - -// template K512(x) { -// signal output out[64]; -// var c[80] = [ -// 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, -// 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, -// 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, -// 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, -// 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab, -// 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, -// 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, -// 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, -// 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, -// 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, -// 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, -// 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, -// 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c, -// 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6, -// 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, -// 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 -// ]; - -// for (var i=0; i<64; i++) { -// out[i] <== (c[x] >> i) & 1; -// } -// } \ No newline at end of file diff --git a/sha512/maj.go b/sha512/maj.go deleted file mode 100644 index 50dc073..0000000 --- a/sha512/maj.go +++ /dev/null @@ -1,33 +0,0 @@ -package sha512 - -import ( - "github.com/consensys/gnark/frontend" -) - -func Maj_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") } - mid := make([] frontend.Variable, n) - out := make([] frontend.Variable, n) - for k := 0; k < n; k++ { - mid[k] = api.Mul(b[k], c[k]) - out[k] = api.Add(api.Mul(a[k], api.Sub(api.Add(b[k], c[k]), api.Mul(2, mid[k]))), mid[k]) - } - return out -} - - -// template Maj_t512(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> k) & 1 - } - - fmt.Println(paddedIn) - - var h512Components [8][64]frontend.Variable - - for i := 0; i < 8; i++ { - h512Components[i] = H512(uint(i)) - } - - sha512compression := make([][] frontend.Variable, nBlocks) - - for i := 0; i < nBlocks; i++ { - var hin = make([] frontend.Variable, 64 * 8) - var inp = make([] frontend.Variable, 1024) - if i == 0 { - for k := 0; k < 64; k++ { - for j := 0; j < 8; j++ { - hin[j*64 + k] = h512Components[j][k] - } - } - } else { - for k := 0; k < 64; k++ { - for j := 0; j < 8; j++ { - hin[j*64 + k] = sha512compression[i-1][64*j+63-k] - } - } - } - for k := 0; k < 1024; k++ { - inp[k] = paddedIn[i*1024 + k] - } - sha512compression[i] = Sha512compression(api, hin, inp) - } - - var out [512]frontend.Variable - - for k := 0; k < 512; k++ { - out[k] = sha512compression[nBlocks-1][k] - - } - - return out -} diff --git a/sha512/sha512compression.go b/sha512/sha512compression.go deleted file mode 100644 index af3465b..0000000 --- a/sha512/sha512compression.go +++ /dev/null @@ -1,190 +0,0 @@ -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(uint(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(api, 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(api, h[t][:], e[t][:], f[t][:], g[t][:], ct_k[t][:], w[t][:]) - t2 := T2_512(api, 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(api, d[t][:], t1) - suma := BinSum(api, 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_in[0][0][k] = hin[64*0+k] - fsum_in[0][1][k] = a[80][k] - fsum_in[1][0][k] = hin[64*1+k] - fsum_in[1][1][k] = b[80][k] - fsum_in[2][0][k] = hin[64*2+k] - fsum_in[2][1][k] = c[80][k] - fsum_in[3][0][k] = hin[64*3+k] - fsum_in[3][1][k] = d[80][k] - fsum_in[4][0][k] = hin[64*4+k] - fsum_in[4][1][k] = e[80][k] - fsum_in[5][0][k] = hin[64*5+k] - fsum_in[5][1][k] = f[80][k] - fsum_in[6][0][k] = hin[64*6+k] - fsum_in[6][1][k] = g[80][k] - fsum_in[7][0][k] = hin[64*7+k] - fsum_in[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(api, 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/sha_test.go b/sha512/sha_test.go index 8b41fbb..19d9a75 100644 --- a/sha512/sha_test.go +++ b/sha512/sha_test.go @@ -6,6 +6,7 @@ import ( "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/test" + "github.com/consensys/gnark-crypto/ecc" ) type Sha512Circuit struct { @@ -22,6 +23,8 @@ func (circuit *Sha512Circuit) Define(api frontend.API) error { return nil } +var testCurve = ecc.BN254 + func TestSha512(t *testing.T) { assert := test.NewAssert(t) diff --git a/sha512/shift.go b/sha512/shift.go deleted file mode 100644 index fd55815..0000000 --- a/sha512/shift.go +++ /dev/null @@ -1,32 +0,0 @@ -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 deleted file mode 100644 index 30d9766..0000000 --- a/sha512/sigma.go +++ /dev/null @@ -1,81 +0,0 @@ -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(api, in, ra) - rotb := RotR512(api, in, rb) - shrc := ShR512(api, in, rc) - - return Xor3_512(api, 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(api, in, ra) - rotb := RotR512(api, in, rb) - rotc := RotR512(api, in, rc) - - return Xor3_512(api, 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 deleted file mode 100644 index 4ac5a78..0000000 --- a/sha512/sigmaplus.go +++ /dev/null @@ -1,49 +0,0 @@ -package sha512 - -import ( - "github.com/consensys/gnark/frontend" -) - - -func SigmaPlus512(api frontend.API, in2, in7, in15, in16 []frontend.Variable) ([64]frontend.Variable) { - if len(in2) != 64 { panic("bad length") } - - sigma1 := SmallSigma512(api, in2, 19, 61, 6) - sigma0 := SmallSigma512(api, in15, 1, 8, 7) - - inter := BinSum(api, sigma1, in7, sigma0, in16) - var out [64]frontend.Variable - for k := 0; k < 64; k++ { - out[k] = inter[k] - } - return out -} - - -// 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 deleted file mode 100644 index 7234557..0000000 --- a/sha512/t1.go +++ /dev/null @@ -1,55 +0,0 @@ -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(api, e, f, g) - bigsigma1 := BigSigma512(api, e, 14, 18, 41) - - return BinSum(api, 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 deleted file mode 100644 index 586d625..0000000 --- a/sha512/t2.go +++ /dev/null @@ -1,45 +0,0 @@ -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(api, a, 28, 34, 39) - maj := Maj_t512(api, a, b, c) - - return BinSum(api, 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/utils.go b/sha512/utils.go deleted file mode 100644 index 6661197..0000000 --- a/sha512/utils.go +++ /dev/null @@ -1,19 +0,0 @@ -package sha512 - -import ("math/big") - -func newBigInt(s string) *big.Int { - result, success := new(big.Int).SetString(s, 16) - if !success { - panic("invalid bigint") - } - return result -} - -func newBigIntBase10(s string) *big.Int { - result, success := new(big.Int).SetString(s, 10) - if !success { - panic("invalid bigint") - } - return result -} \ No newline at end of file diff --git a/sha512/xor3.go b/sha512/xor3.go deleted file mode 100644 index 599052a..0000000 --- a/sha512/xor3.go +++ /dev/null @@ -1,35 +0,0 @@ -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)) - q := api.Mul(a[k], p) - out[k] = api.Add(q, b[k], c[k], api.Mul(-2, mid)) - // 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 Date: Tue, 4 Oct 2022 19:43:22 +0000 Subject: [PATCH 11/11] rename --- sha512/{pysha512.go => sha512.go} | 2 +- sha512/sha_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename sha512/{pysha512.go => sha512.go} (98%) diff --git a/sha512/pysha512.go b/sha512/sha512.go similarity index 98% rename from sha512/pysha512.go rename to sha512/sha512.go index d4c8818..fc1358e 100644 --- a/sha512/pysha512.go +++ b/sha512/sha512.go @@ -15,7 +15,7 @@ func _right_rotate(n [64]frontend.Variable, bits int) [64]frontend.Variable { return result } -func PySha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variable) { +func Sha512(api frontend.API, in [] frontend.Variable) ([512] frontend.Variable) { _not := func(x [64]frontend.Variable) [64]frontend.Variable { return not(api, x) } diff --git a/sha512/sha_test.go b/sha512/sha_test.go index 19d9a75..c1ef941 100644 --- a/sha512/sha_test.go +++ b/sha512/sha_test.go @@ -15,7 +15,7 @@ type Sha512Circuit struct { } func (circuit *Sha512Circuit) Define(api frontend.API) error { - res := PySha512(api, circuit.in) + res := Sha512(api, circuit.in) if len(res) != 512 { panic("bad length") } for i := 0; i < 512; i++ { api.AssertIsEqual(res[i], circuit.out[i])