From 20f12cd0cf717a9bdf24bd5c391e10c5e8187d8d Mon Sep 17 00:00:00 2001 From: Marcin Kostrzewa Date: Tue, 10 Dec 2024 15:25:40 +0000 Subject: [PATCH] add skyscraper arthur --- arthur.go | 86 ++++++++++++++++++++++++++++++++++++++++ example/main.go | 98 +++++++++++++++++++++++++++++++++++++++++++++- go.mod | 1 + go.sum | 2 + hash/keccak.go | 6 ++- hash/skyscraper.go | 53 +++++++++++++++++++++++++ hash/sponge.go | 7 ++-- io_pattern.go | 2 +- safe.go | 9 ++--- 9 files changed, 250 insertions(+), 14 deletions(-) create mode 100644 hash/skyscraper.go diff --git a/arthur.go b/arthur.go index 39ded16..1a5632e 100644 --- a/arthur.go +++ b/arthur.go @@ -2,9 +2,12 @@ package gnark_nimue import ( "fmt" + "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/frontend" + bits2 "github.com/consensys/gnark/std/math/bits" "github.com/consensys/gnark/std/math/uints" "github.com/reilabs/gnark-nimue/hash" + skyscraper "github.com/reilabs/gnark-skyscraper" "math/big" ) @@ -95,3 +98,86 @@ func (arthur *byteArthur[H]) PrintState(api frontend.API) { api.Println(msg) arthur.safe.sponge.PrintState(api) } + +type nativeArthur[H hash.DuplexHash[frontend.Variable]] struct { + api frontend.API + transcript []uints.U8 + safe *Safe[frontend.Variable, H] +} + +func (arthur *nativeArthur[H]) FillNextBytes(uints []uints.U8) error { + copy(uints, arthur.transcript) + for _, i := range uints { + err := arthur.safe.Absorb([]frontend.Variable{i.Val}) + if err != nil { + return err + } + } + return nil +} + +func randomBytesInModulus(api frontend.API) (int, error) { + if api.Compiler().Field().Cmp(ecc.BN254.ScalarField()) == 0 { + return 15, nil + } + return 0, fmt.Errorf("unsupported field") +} + +func (arthur *nativeArthur[H]) FillChallengeBytes(out []uints.U8) error { + numBytes, err := randomBytesInModulus(arthur.api) + if err != nil { + return err + } + if len(out) == 0 { + return nil + } + lenGood := min(len(out), numBytes) + tmp := make([]frontend.Variable, 1) + err = arthur.FillNextScalars(tmp) + if err != nil { + return err + } + bits := bits2.ToBinary(arthur.api, tmp[0]) + for i := 0; i < lenGood; i++ { + out[i] = uints.NewU8(0) + curMul := 1 + for j := range 8 { + out[i].Val = arthur.api.Add(arthur.api.Mul(curMul, bits[8*i+j]), out[i].Val) + curMul *= 2 + } + } + return nil +} + +func (arthur *nativeArthur[H]) FillNextScalars(out []frontend.Variable) error { + wordSize := (arthur.api.Compiler().FieldBitLen() + 7) / 8 + for i := range out { + bytes := arthur.transcript[:wordSize] + arthur.transcript = arthur.transcript[wordSize:] + out[i] = frontend.Variable(0) + curMul := big.NewInt(1) + for _, b := range bytes { + out[i] = arthur.api.Add(out[i], arthur.api.Mul(b.Val, curMul)) + curMul.Mul(curMul, big.NewInt(256)) + } + } + err := arthur.safe.Absorb(out) + return err +} + +func (arthur *nativeArthur[H]) FillChallengeScalars(out []frontend.Variable) error { + return arthur.safe.Squeeze(out) +} + +func (arthur *nativeArthur[H]) PrintState(api frontend.API) { + arthur.safe.sponge.PrintState(api) +} + +func NewSkyscraperArthur(api frontend.API, sc *skyscraper.Skyscraper, io []byte, transcript []uints.U8) (Arthur, error) { + sponge, err := hash.NewSkyScraper(sc) + if err != nil { + return nil, err + } + safe, err := NewSafe[frontend.Variable, hash.Skyscraper](sponge, io) + return &nativeArthur[hash.Skyscraper]{api, transcript, safe}, nil +} diff --git a/example/main.go b/example/main.go index dbd97d9..2c1c9f4 100644 --- a/example/main.go +++ b/example/main.go @@ -8,6 +8,7 @@ import ( "github.com/consensys/gnark/frontend/cs/r1cs" "github.com/consensys/gnark/std/math/uints" gnark_nimue "github.com/reilabs/gnark-nimue" + skyscraper "github.com/reilabs/gnark-skyscraper" ) type TestCircuit struct { @@ -184,6 +185,101 @@ func ExampleWhir() { fmt.Printf("%v\n", vErr) } +type WhirSkyscraperCircuit struct { + IO []byte + Transcript [2312]uints.U8 `gnark:",public"` +} + +func (circuit *WhirSkyscraperCircuit) Define(api frontend.API) error { + sc := skyscraper.NewSkyscraper(api, 2) + arthur, err := gnark_nimue.NewSkyscraperArthur(api, sc, circuit.IO, circuit.Transcript[:]) + if err != nil { + return err + } + + merkleRoot := make([]frontend.Variable, 1) + err = arthur.FillNextScalars(merkleRoot) + if err != nil { + return err + } + + api.Println(merkleRoot...) + + oodCh := [1]frontend.Variable{} + err = arthur.FillChallengeScalars(oodCh[:]) + if err != nil { + return err + } + api.Println(oodCh[:]...) + + oodAns := [1]frontend.Variable{} + err = arthur.FillNextScalars(oodAns[:]) + if err != nil { + return err + } + api.Println(oodAns[:]...) + + initialCombinationRandomness := [1]frontend.Variable{} + err = arthur.FillChallengeScalars(initialCombinationRandomness[:]) + if err != nil { + return err + } + api.Println(initialCombinationRandomness[0]) + + for range 4 { + sumcheckPolyEvals := [3]frontend.Variable{} + err = arthur.FillNextScalars(sumcheckPolyEvals[:]) + if err != nil { + return err + } + api.Println(sumcheckPolyEvals[:]...) + + foldingRandomnessSingle := [1]frontend.Variable{} + err = arthur.FillChallengeScalars(foldingRandomnessSingle[:]) + if err != nil { + return err + } + api.Println(foldingRandomnessSingle[0]) + } + + return nil +} + +func ExampleWhirSkyScraper() { + ioPat := "🌪\ufe0f\u0000A1merkle_digest\u0000S1ood_query\u0000A1ood_ans\u0000S1initial_combination_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A1merkle_digest\u0000S1ood_query\u0000A1ood_ans\u0000S17stir_queries\u0000S3pow_queries\u0000A8pow-nonce\u0000S1combination_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A1merkle_digest\u0000S1ood_query\u0000A1ood_ans\u0000S3stir_queries\u0000S3pow_queries\u0000A8pow-nonce\u0000S1combination_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A1merkle_digest\u0000S1ood_query\u0000A1ood_ans\u0000S2stir_queries\u0000S3pow_queries\u0000A8pow-nonce\u0000S1combination_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A1merkle_digest\u0000S1ood_query\u0000A1ood_ans\u0000S2stir_queries\u0000S3pow_queries\u0000A8pow-nonce\u0000S1combination_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A3sumcheck_poly\u0000S1folding_randomness\u0000A1final_coeffs\u0000S1final_queries\u0000S3pow_queries\u0000A8pow-nonce" + io := gnark_nimue.IOPattern{} + _ = io.Parse([]byte(ioPat)) + fmt.Printf("io: %s\n", io.PPrint()) + + circ := WhirSkyscraperCircuit{ + IO: []byte(ioPat), + } + + ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circ) + if err != nil { + fmt.Println(err) + return + } + pk, vk, _ := groth16.Setup(ccs) + transcriptBytes := [2312]byte{145, 161, 51, 30, 17, 249, 191, 189, 138, 135, 162, 50, 48, 19, 72, 191, 143, 92, 125, 50, 164, 84, 45, 78, 46, 100, 223, 183, 172, 125, 52, 44, 208, 242, 161, 135, 200, 32, 189, 248, 221, 229, 8, 0, 247, 198, 49, 102, 76, 167, 255, 4, 175, 156, 198, 58, 207, 254, 193, 17, 142, 218, 242, 33, 249, 38, 98, 249, 37, 215, 159, 251, 110, 222, 124, 76, 107, 17, 215, 167, 227, 237, 153, 187, 19, 201, 82, 102, 179, 153, 172, 235, 64, 84, 65, 4, 215, 203, 63, 142, 162, 73, 29, 253, 110, 7, 140, 179, 139, 181, 90, 190, 104, 185, 101, 73, 155, 211, 115, 212, 27, 101, 21, 38, 77, 134, 177, 29, 20, 231, 224, 183, 146, 39, 108, 255, 61, 234, 61, 170, 88, 93, 57, 205, 165, 123, 85, 160, 124, 118, 151, 7, 68, 143, 79, 241, 225, 98, 208, 9, 84, 165, 193, 163, 117, 216, 5, 233, 8, 254, 1, 200, 253, 35, 101, 200, 105, 86, 177, 97, 185, 142, 141, 201, 228, 144, 61, 88, 214, 251, 100, 7, 148, 75, 122, 127, 61, 235, 136, 125, 168, 239, 165, 214, 30, 212, 253, 99, 38, 153, 160, 188, 101, 125, 80, 137, 184, 4, 89, 155, 168, 169, 26, 32, 242, 199, 69, 106, 112, 118, 123, 199, 232, 219, 10, 122, 93, 107, 184, 81, 98, 164, 27, 230, 86, 214, 88, 32, 204, 123, 42, 14, 102, 161, 123, 43, 173, 138, 9, 207, 254, 181, 2, 96, 113, 28, 124, 228, 193, 161, 16, 156, 218, 169, 143, 126, 112, 69, 230, 244, 86, 214, 122, 95, 85, 13, 133, 10, 74, 180, 116, 102, 188, 116, 167, 242, 74, 86, 44, 37, 122, 153, 82, 98, 18, 35, 77, 69, 187, 148, 144, 116, 26, 212, 197, 53, 122, 224, 39, 29, 194, 142, 194, 186, 144, 113, 4, 186, 207, 193, 63, 211, 215, 41, 138, 62, 188, 52, 158, 2, 8, 179, 220, 201, 16, 152, 47, 31, 102, 192, 55, 47, 112, 70, 254, 227, 62, 182, 42, 220, 226, 234, 116, 133, 180, 207, 131, 162, 106, 6, 61, 151, 84, 180, 90, 218, 109, 29, 148, 244, 12, 45, 11, 20, 230, 22, 140, 87, 208, 189, 83, 9, 129, 120, 195, 238, 144, 141, 228, 47, 184, 90, 120, 83, 187, 186, 211, 218, 217, 242, 77, 84, 35, 102, 49, 46, 210, 161, 166, 181, 16, 210, 205, 166, 88, 249, 38, 182, 146, 50, 156, 70, 213, 166, 52, 214, 73, 207, 78, 129, 45, 208, 214, 29, 133, 140, 3, 27, 223, 89, 65, 96, 200, 106, 43, 78, 161, 184, 171, 145, 235, 198, 9, 149, 111, 106, 246, 52, 66, 134, 36, 170, 230, 160, 145, 95, 10, 110, 162, 29, 15, 134, 228, 172, 30, 11, 170, 202, 46, 42, 253, 10, 43, 201, 207, 119, 141, 28, 40, 4, 46, 139, 228, 43, 251, 4, 187, 17, 87, 217, 15, 27, 0, 0, 0, 0, 0, 11, 180, 248, 172, 54, 127, 92, 252, 119, 149, 39, 49, 3, 99, 226, 166, 21, 126, 72, 128, 121, 138, 228, 221, 111, 25, 8, 19, 111, 123, 48, 33, 133, 57, 30, 118, 28, 71, 66, 36, 249, 33, 205, 121, 100, 211, 170, 47, 181, 28, 231, 81, 235, 111, 149, 232, 133, 154, 238, 8, 165, 227, 85, 8, 4, 254, 46, 140, 181, 206, 8, 230, 77, 235, 106, 204, 239, 34, 243, 30, 7, 132, 80, 86, 17, 128, 234, 123, 93, 237, 72, 174, 109, 70, 230, 45, 49, 197, 43, 186, 39, 43, 60, 42, 234, 235, 26, 247, 233, 154, 94, 128, 255, 228, 221, 43, 186, 186, 21, 91, 67, 123, 149, 18, 137, 87, 110, 133, 89, 191, 12, 27, 57, 5, 132, 150, 167, 154, 170, 185, 208, 250, 107, 174, 46, 213, 55, 241, 125, 153, 138, 59, 78, 158, 156, 57, 79, 229, 172, 124, 227, 163, 9, 89, 74, 206, 13, 144, 49, 136, 118, 38, 18, 121, 79, 190, 240, 144, 130, 150, 221, 226, 62, 165, 181, 178, 238, 96, 4, 14, 208, 215, 0, 117, 27, 67, 210, 10, 197, 93, 99, 9, 28, 110, 16, 116, 233, 138, 94, 201, 93, 39, 171, 193, 188, 173, 23, 207, 81, 101, 222, 105, 130, 85, 83, 152, 23, 151, 16, 31, 145, 115, 45, 143, 26, 102, 134, 27, 177, 101, 228, 215, 15, 108, 246, 124, 157, 0, 140, 228, 220, 252, 208, 59, 25, 199, 18, 209, 17, 175, 79, 208, 255, 70, 158, 239, 124, 189, 244, 198, 122, 96, 137, 239, 74, 124, 43, 145, 121, 87, 168, 152, 51, 253, 21, 155, 95, 37, 240, 243, 40, 249, 255, 73, 76, 172, 8, 191, 88, 132, 229, 137, 225, 101, 36, 189, 41, 185, 200, 94, 131, 103, 19, 186, 222, 101, 24, 181, 106, 62, 186, 232, 2, 252, 144, 112, 245, 7, 36, 228, 198, 240, 52, 91, 254, 17, 35, 183, 116, 174, 43, 210, 72, 110, 156, 247, 73, 36, 253, 75, 205, 140, 181, 72, 28, 126, 114, 98, 141, 62, 155, 64, 204, 11, 34, 206, 75, 194, 70, 111, 253, 234, 47, 125, 96, 208, 216, 29, 173, 247, 88, 167, 67, 134, 35, 72, 18, 217, 107, 170, 118, 83, 206, 199, 193, 120, 168, 251, 138, 124, 55, 20, 221, 28, 111, 49, 44, 16, 23, 16, 120, 181, 10, 236, 206, 6, 187, 168, 47, 171, 133, 215, 89, 158, 220, 111, 154, 190, 53, 121, 101, 108, 199, 69, 218, 193, 180, 186, 223, 240, 237, 90, 118, 30, 40, 190, 23, 34, 10, 108, 1, 0, 0, 0, 0, 0, 1, 73, 185, 93, 169, 52, 83, 24, 151, 111, 92, 66, 61, 4, 54, 147, 105, 170, 246, 164, 240, 84, 198, 238, 39, 213, 143, 239, 5, 185, 221, 208, 29, 165, 9, 88, 53, 128, 228, 58, 126, 239, 129, 205, 99, 206, 57, 54, 85, 203, 6, 216, 71, 8, 90, 147, 92, 28, 162, 122, 19, 207, 28, 16, 96, 146, 31, 131, 55, 195, 133, 33, 208, 158, 187, 117, 11, 4, 104, 15, 255, 93, 157, 138, 250, 141, 7, 113, 39, 210, 126, 124, 31, 187, 143, 168, 170, 221, 34, 72, 174, 59, 254, 135, 111, 133, 10, 137, 73, 95, 158, 103, 13, 74, 207, 45, 160, 133, 76, 31, 47, 43, 127, 19, 234, 213, 191, 216, 233, 136, 40, 163, 221, 146, 203, 74, 241, 120, 136, 13, 172, 238, 26, 165, 188, 198, 129, 16, 77, 54, 46, 233, 95, 242, 21, 11, 66, 193, 138, 224, 176, 106, 1, 71, 181, 255, 65, 32, 203, 169, 80, 232, 129, 86, 94, 74, 103, 93, 64, 229, 172, 168, 89, 12, 14, 183, 98, 138, 205, 244, 155, 41, 250, 149, 20, 227, 238, 254, 175, 190, 193, 14, 97, 201, 207, 172, 52, 10, 42, 85, 196, 175, 236, 43, 132, 11, 91, 161, 20, 173, 170, 248, 161, 246, 218, 49, 30, 50, 106, 229, 210, 95, 83, 92, 213, 81, 135, 39, 2, 47, 99, 59, 57, 182, 182, 29, 131, 38, 34, 61, 178, 147, 139, 212, 182, 227, 131, 72, 1, 37, 233, 5, 155, 149, 24, 144, 68, 163, 194, 24, 249, 164, 214, 167, 251, 94, 187, 89, 112, 48, 57, 185, 155, 94, 83, 15, 44, 164, 192, 181, 11, 236, 5, 180, 143, 195, 187, 83, 90, 68, 10, 160, 205, 57, 83, 121, 223, 216, 242, 35, 100, 230, 5, 194, 250, 122, 122, 136, 203, 212, 3, 214, 25, 158, 125, 137, 82, 43, 192, 193, 219, 4, 61, 232, 169, 200, 1, 138, 87, 149, 121, 232, 84, 252, 215, 235, 141, 68, 238, 66, 60, 118, 96, 119, 42, 223, 234, 50, 49, 14, 58, 57, 175, 183, 217, 110, 71, 20, 94, 143, 38, 200, 105, 236, 231, 65, 1, 41, 6, 146, 20, 250, 72, 100, 63, 99, 3, 249, 250, 66, 249, 170, 192, 132, 203, 219, 27, 65, 73, 52, 33, 210, 230, 170, 30, 222, 151, 166, 65, 154, 15, 66, 154, 103, 247, 80, 77, 116, 26, 74, 29, 17, 89, 124, 51, 127, 3, 63, 61, 90, 93, 229, 254, 211, 206, 100, 46, 156, 225, 236, 105, 170, 2, 199, 217, 171, 228, 40, 118, 3, 41, 0, 0, 0, 0, 0, 1, 129, 226, 210, 0, 195, 118, 193, 134, 253, 13, 145, 166, 48, 144, 131, 168, 62, 238, 65, 133, 247, 59, 167, 5, 197, 246, 107, 144, 97, 249, 26, 48, 45, 11, 177, 145, 35, 235, 62, 40, 66, 241, 85, 254, 82, 65, 189, 59, 220, 140, 31, 32, 129, 75, 253, 86, 109, 232, 2, 112, 47, 196, 113, 28, 44, 30, 160, 89, 68, 69, 110, 218, 115, 94, 19, 113, 19, 122, 40, 228, 41, 109, 246, 225, 114, 160, 7, 78, 130, 33, 229, 32, 206, 26, 200, 186, 24, 27, 60, 194, 216, 33, 189, 214, 116, 165, 2, 210, 135, 166, 251, 114, 26, 120, 149, 4, 163, 177, 102, 88, 43, 227, 55, 190, 182, 104, 159, 58, 226, 27, 174, 244, 241, 252, 77, 77, 218, 163, 45, 208, 190, 60, 135, 50, 5, 143, 104, 25, 200, 215, 205, 237, 54, 120, 34, 64, 9, 5, 204, 149, 246, 44, 221, 49, 80, 82, 137, 94, 16, 21, 32, 86, 41, 228, 110, 178, 31, 84, 93, 36, 177, 24, 173, 199, 125, 152, 129, 200, 221, 141, 233, 210, 179, 24, 44, 249, 77, 45, 62, 189, 52, 10, 212, 250, 57, 222, 12, 19, 170, 135, 120, 45, 12, 11, 69, 211, 182, 150, 79, 20, 167, 6, 203, 4, 81, 6, 3, 226, 141, 65, 199, 118, 138, 117, 125, 127, 54, 97, 158, 220, 8, 27, 20, 41, 229, 141, 203, 181, 30, 227, 27, 165, 13, 184, 10, 50, 195, 3, 2, 152, 32, 122, 198, 124, 15, 23, 138, 223, 218, 121, 50, 53, 231, 166, 158, 19, 22, 111, 133, 15, 151, 224, 115, 59, 14, 145, 133, 2, 148, 1, 200, 68, 133, 47, 168, 71, 69, 59, 55, 121, 157, 6, 48, 48, 182, 24, 110, 20, 224, 64, 248, 139, 189, 112, 42, 101, 76, 114, 186, 136, 219, 11, 58, 188, 8, 23, 135, 165, 66, 242, 243, 22, 156, 206, 84, 74, 182, 3, 62, 203, 160, 29, 75, 147, 89, 176, 57, 170, 208, 222, 198, 96, 17, 16, 176, 53, 248, 246, 247, 158, 109, 216, 219, 220, 21, 53, 48, 10, 219, 60, 221, 212, 253, 75, 217, 24, 249, 163, 44, 196, 156, 131, 224, 200, 42, 31, 100, 55, 131, 217, 183, 130, 19, 99, 116, 171, 252, 153, 16, 83, 191, 63, 118, 194, 241, 139, 50, 210, 63, 94, 91, 219, 215, 45, 252, 152, 126, 24, 88, 241, 66, 173, 11, 191, 158, 172, 223, 92, 162, 23, 41, 248, 77, 210, 44, 104, 77, 147, 182, 162, 30, 19, 66, 230, 100, 34, 123, 227, 249, 16, 0, 0, 0, 0, 0, 0, 3, 245, 67, 18, 44, 41, 192, 163, 187, 120, 210, 171, 253, 202, 40, 228, 70, 35, 177, 126, 237, 52, 158, 233, 96, 117, 58, 144, 183, 176, 235, 194, 1, 28, 180, 87, 183, 208, 59, 108, 116, 200, 17, 135, 37, 167, 183, 161, 98, 170, 215, 153, 201, 90, 107, 193, 46, 186, 56, 92, 26, 179, 176, 45, 31, 5, 219, 15, 64, 157, 157, 222, 141, 209, 183, 144, 141, 187, 51, 210, 101, 15, 37, 142, 87, 23, 106, 139, 118, 130, 208, 105, 119, 21, 253, 29, 133, 47, 202, 95, 97, 154, 25, 219, 213, 65, 129, 54, 174, 98, 118, 63, 202, 163, 250, 236, 249, 74, 88, 40, 113, 41, 104, 181, 217, 57, 7, 244, 13, 35, 249, 44, 57, 203, 154, 218, 9, 52, 64, 230, 104, 197, 95, 127, 222, 153, 124, 145, 232, 170, 211, 197, 109, 204, 20, 252, 226, 215, 250, 19, 250, 16, 10, 104, 155, 249, 133, 158, 17, 78, 121, 247, 217, 220, 37, 64, 148, 120, 244, 80, 209, 41, 11, 164, 250, 61, 151, 139, 246, 46, 60, 220, 194, 10, 235, 239, 194, 254, 243, 140, 66, 4, 9, 27, 123, 124, 127, 23, 134, 116, 136, 73, 109, 185, 147, 234, 155, 81, 53, 54, 37, 81, 233, 94, 177, 1, 185, 175, 118, 213, 106, 97, 161, 202, 156, 76, 169, 31, 110, 26, 11, 135, 221, 203, 139, 171, 73, 129, 252, 145, 184, 127, 153, 104, 252, 102, 112, 21, 155, 162, 97, 183, 63, 131, 186, 209, 95, 49, 212, 92, 80, 77, 92, 27, 173, 226, 101, 147, 224, 158, 196, 3, 172, 197, 204, 174, 71, 122, 8, 32, 255, 148, 179, 66, 220, 198, 57, 196, 159, 230, 140, 184, 6, 144, 185, 11, 79, 129, 227, 95, 7, 58, 16, 32, 143, 198, 233, 108, 77, 156, 252, 3, 167, 239, 80, 95, 222, 169, 209, 40, 117, 195, 183, 81, 121, 67, 206, 253, 248, 4, 87, 17, 11, 236, 222, 255, 246, 252, 5, 189, 150, 81, 15, 3, 14, 44, 139, 254, 120, 244, 85, 22, 183, 9, 72, 103, 226, 196, 109, 206, 58, 193, 70, 139, 248, 51, 49, 158, 108, 135, 135, 185, 61, 199, 87, 24, 20, 186, 251, 190, 149, 120, 197, 4, 168, 164, 95, 119, 149, 165, 26, 81, 94, 198, 147, 47, 30, 116, 242, 210, 83, 7, 91, 47, 253, 95, 71, 48, 0, 0, 0, 0, 0, 0, 2, 12} + transcript := [2312]uints.U8{} + for i := range transcriptBytes { + transcript[i] = uints.NewU8(transcriptBytes[i]) + } + + assignment := WhirSkyscraperCircuit{ + IO: []byte(ioPat), + Transcript: transcript, + } + + witness, _ := frontend.NewWitness(&assignment, ecc.BN254.ScalarField()) + publicWitness, _ := witness.Public() + + proof, _ := groth16.Prove(ccs, pk, witness) + vErr := groth16.Verify(proof, vk, publicWitness) + fmt.Printf("%v\n", vErr) +} + func main() { - ExampleWhir() + ExampleWhirSkyScraper() } diff --git a/go.mod b/go.mod index eb7c730..b79d98c 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/reilabs/gnark-skyscraper v0.0.0-20241203164459-07cdbaf96dc3 // indirect github.com/ronanh/intcomp v1.1.0 // indirect github.com/rs/zerolog v1.33.0 // indirect github.com/x448/float16 v0.8.4 // indirect diff --git a/go.sum b/go.sum index 2f638cf..ebe2709 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,8 @@ github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFV github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/reilabs/gnark-skyscraper v0.0.0-20241203164459-07cdbaf96dc3 h1:ZDD1xCjaYJwQNRGCokPGFZUEnrsuy2kxSjkSsPKLhxY= +github.com/reilabs/gnark-skyscraper v0.0.0-20241203164459-07cdbaf96dc3/go.mod h1:DNZzTzHHeHeBsMWkDRJFkK1T1p5HrAicpSOS05mGHa8= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/ronanh/intcomp v1.1.0 h1:i54kxmpmSoOZFcWPMWryuakN0vLxLswASsGa07zkvLU= diff --git a/hash/keccak.go b/hash/keccak.go index 0185d22..ac2b739 100644 --- a/hash/keccak.go +++ b/hash/keccak.go @@ -19,8 +19,10 @@ func (k *KeccakState) R() int { return 136 } -func (k *KeccakState) Initialize(iv [32]uints.U8) { - copy(k.state[k.R():k.R()+32], iv[:]) +func (k *KeccakState) Initialize(iv [32]byte) { + for i := range 32 { + k.state[k.R()+i] = uints.NewU8(iv[i]) + } } func (k *KeccakState) Permute() { diff --git a/hash/skyscraper.go b/hash/skyscraper.go new file mode 100644 index 0000000..3d87122 --- /dev/null +++ b/hash/skyscraper.go @@ -0,0 +1,53 @@ +package hash + +import ( + "github.com/consensys/gnark/frontend" + skyscraper "github.com/reilabs/gnark-skyscraper" + "math/big" + "slices" +) + +type SkyscraperState struct { + skyscraper *skyscraper.Skyscraper + s [2]frontend.Variable +} + +func (s *SkyscraperState) N() int { + return 2 +} + +func (s *SkyscraperState) R() int { + return 1 +} + +func (s *SkyscraperState) Initialize(iv [32]byte) { + slices.Reverse(iv[:]) + felt := new(big.Int).SetBytes(iv[:]) + s.s[0] = 0 + s.s[1] = felt +} + +func (s *SkyscraperState) Permute() { + s.skyscraper.Permute(&s.s) +} + +func (s *SkyscraperState) State() []frontend.Variable { + return s.s[:] +} + +func (s *SkyscraperState) Zeroize(index int) { + s.s[0] = 0 + s.s[1] = 0 +} + +func (s *SkyscraperState) PrintState(api frontend.API) { + api.Println(s.s[:]...) +} + +type Skyscraper DuplexHash[frontend.Variable] + +func NewSkyScraper(sc *skyscraper.Skyscraper) (Skyscraper, error) { + return &DuplexSponge[frontend.Variable, *SkyscraperState]{ + sponge: &SkyscraperState{skyscraper: sc}, + }, nil +} diff --git a/hash/sponge.go b/hash/sponge.go index c015a57..fe6d751 100644 --- a/hash/sponge.go +++ b/hash/sponge.go @@ -3,13 +3,12 @@ package hash import ( "fmt" "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/std/math/uints" ) type Sponge[U any] interface { N() int R() int - Initialize(iv [32]uints.U8) + Initialize(iv [32]byte) Permute() State() []U Zeroize(index int) @@ -17,7 +16,7 @@ type Sponge[U any] interface { } type DuplexHash[U any] interface { - Initialize(iv [32]uints.U8) + Initialize(iv [32]byte) Absorb(data []U) Squeeze(out []U) Ratchet() @@ -30,7 +29,7 @@ type DuplexSponge[U any, S Sponge[U]] struct { squeezePos int } -func (s *DuplexSponge[U, S]) Initialize(iv [32]uints.U8) { +func (s *DuplexSponge[U, S]) Initialize(iv [32]byte) { s.sponge.Initialize(iv) s.absorbPos = 0 s.squeezePos = s.sponge.R() diff --git a/io_pattern.go b/io_pattern.go index 2bde38c..4c192e7 100644 --- a/io_pattern.go +++ b/io_pattern.go @@ -130,7 +130,7 @@ func (stack *OpQueue) doOp(kind OpKind, size uint64) error { return nil } if stack.ops[0].Size < size { - return fmt.Errorf("OpStack.doOp: size mismatch") + return fmt.Errorf("OpStack.doOp: %v size mismatch, have %d, requested %d", kind, stack.ops[0].Size, size) } stack.ops = stack.ops[1:] return nil diff --git a/safe.go b/safe.go index 7bf7a10..34575dc 100644 --- a/safe.go +++ b/safe.go @@ -2,7 +2,6 @@ package gnark_nimue import ( "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/std/math/uints" "github.com/reilabs/gnark-nimue/hash" _ "unsafe" ) @@ -30,7 +29,7 @@ func keccakF(a *[200]byte) { } } -func generateTag(io []byte) [32]uints.U8 { +func generateTag(io []byte) [32]byte { state := [200]byte{} absorbPos := 0 R := 136 @@ -47,10 +46,8 @@ func generateTag(io []byte) [32]uints.U8 { } } keccakF(&state) - tag := [32]uints.U8{} - for i := 0; i < 32; i++ { - tag[i] = uints.NewU8(state[i]) - } + tag := [32]byte{} + copy(tag[:], state[:32]) return tag }