A very experimental PLC implementation which uses BFT consensus for decentralization
at main 94 lines 2.7 kB view raw
1package proof 2 3import ( 4 "encoding/hex" 5 "slices" 6 "testing" 7 "time" 8 9 "github.com/consensys/gnark-crypto/ecc" 10 "github.com/consensys/gnark-crypto/ecc/bn254" 11 "github.com/consensys/gnark/backend/groth16" 12 "github.com/consensys/gnark/frontend" 13 "github.com/consensys/gnark/frontend/cs/r1cs" 14 "github.com/samber/lo" 15 "github.com/stretchr/testify/require" 16 17 "github.com/consensys/gnark-crypto/ecc/bn254/fr/mimc" 18) 19 20func TestBlockChallenge(t *testing.T) { 21 st := time.Now() 22 23 var bcCircuit BlockChallengeCircuit 24 r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &bcCircuit) 25 require.NoError(t, err) 26 27 t.Log("Compile took", time.Since(st)) 28 29 st = time.Now() 30 pk, vk, err := groth16.Setup(r1cs) 31 require.NoError(t, err) 32 t.Log("Setup took", time.Since(st)) 33 34 st = time.Now() 35 origValidatorID := lo.Must(hex.DecodeString("deadbeefdeadbeefdeadbeefdeadbeef")) 36 origLastCommitHash := lo.Must(hex.DecodeString("deadf00ddeadf00ddeadf00ddeadbeef")) 37 38 opDataSlice := slices.Repeat(lo.Must(hex.DecodeString("ffee")), 775) 39 opData := [OperationDataLength]byte{} 40 copy(opData[:], opDataSlice) 41 assignmentShared := buildBlockChallengeCircuitAssignmentShared(origLastCommitHash, opData) 42 assignment := buildBlockChallengeCircuitAssignmentFull(assignmentShared, origValidatorID) 43 t.Log("Out of circuit took", time.Since(st)) 44 45 st = time.Now() 46 witness, err := frontend.NewWitness(assignment, bn254.ID.ScalarField()) 47 require.NoError(t, err) 48 t.Log("Witness took", time.Since(st)) 49 50 st = time.Now() 51 proof, err := groth16.Prove(r1cs, pk, witness) 52 require.NoError(t, err) 53 t.Log("Prove took", time.Since(st)) 54 55 publicWitness, err := witness.Public() 56 require.NoError(t, err) 57 58 st = time.Now() 59 err = groth16.Verify(proof, vk, publicWitness) 60 require.NoError(t, err) 61 t.Log("Verify took", time.Since(st)) 62} 63 64func buildBlockChallengeCircuitAssignmentShared(lastCommitHash []byte, data [OperationDataLength]byte) BlockChallengeCircuit { 65 var assignment BlockChallengeCircuit 66 67 if len(lastCommitHash) > 31 { 68 lastCommitHash = lastCommitHash[len(lastCommitHash)-31:] 69 } 70 assignment.LastCommitHash = lastCommitHash 71 72 for i := 0; i < len(assignment.OperationData); i++ { 73 d := data[31*i : 31*(i+1)] 74 assignment.OperationData[i] = d 75 } 76 77 return assignment 78} 79 80func buildBlockChallengeCircuitAssignmentFull(shared BlockChallengeCircuit, validatorAddress []byte) *BlockChallengeCircuit { 81 h := mimc.NewMiMC() 82 83 h.Write(validatorAddress) 84 h.Write(shared.LastCommitHash.([]byte)) 85 86 for i := 0; i < len(shared.OperationData); i++ { 87 h.Write(shared.OperationData[i].([]byte)) 88 } 89 90 shared.ValidatorAddress = validatorAddress 91 shared.SpecificHash = h.Sum(nil) 92 93 return &shared 94}