From f135f68aa002ac2b321bf7a4d1f3850e1040a8c0 Mon Sep 17 00:00:00 2001 From: hczphn Date: Tue, 10 Dec 2024 19:16:00 -0600 Subject: [PATCH] add logup std --- circuit-std-ecgo/hint.go | 47 ++++++ circuit-std-ecgo/logup.go | 281 +++++++++++++++++++++++++++++++++ circuit-std-ecgo/logup_test.go | 126 +++++++++++++++ circuit-std-ecgo/utils.go | 129 +++++++++++++++ 4 files changed, 583 insertions(+) create mode 100644 circuit-std-ecgo/hint.go create mode 100644 circuit-std-ecgo/logup.go create mode 100644 circuit-std-ecgo/logup_test.go create mode 100644 circuit-std-ecgo/utils.go diff --git a/circuit-std-ecgo/hint.go b/circuit-std-ecgo/hint.go new file mode 100644 index 0000000..60f762c --- /dev/null +++ b/circuit-std-ecgo/hint.go @@ -0,0 +1,47 @@ +package logup + +import ( + "math/big" +) + +func rangeProofHint(q *big.Int, inputs []*big.Int, outputs []*big.Int) error { + n := inputs[0].Int64() + a := new(big.Int).Set(inputs[1]) + + for i := int64(0); i < n/int64(LookupTableBits); i++ { + a, outputs[i] = new(big.Int).DivMod(a, big.NewInt(int64(1< 1 { + n >>= 1 + for i := 0; i < n; i++ { + next = append(next, cur[i*2].Add(api, &cur[i*2+1])) + } + cur = next + next = next[:0] + } + + if len(cur) != 1 { + panic("Summation code may be wrong.") + } + + return cur[0] +} + +func SimpleMin(a uint, b uint) uint { + if a < b { + return a + } else { + return b + } +} + +func GetColumnRandomness(api ecgo.API, n_columns uint, column_combine_options ColumnCombineOptions) []frontend.Variable { + var randomness = make([]frontend.Variable, n_columns) + if column_combine_options == Poly { + beta := api.GetRandomValue() + randomness[0] = 1 + randomness[1] = beta + + // Hopefully this will generate fewer layers than sequential pows + max_deg := uint(1) + for max_deg < n_columns { + for i := max_deg + 1; i <= SimpleMin(max_deg*2, n_columns-1); i++ { + randomness[i] = api.Mul(randomness[max_deg], randomness[i-max_deg]) + } + max_deg *= 2 + } + + // Debug Code: + // for i := 1; i < n_columns; i++ { + // api.AssertIsEqual(randomness[i], api.Mul(randomness[i - 1], beta)) + // } + + } else if column_combine_options == FullRandom { + randomness[0] = 1 + for i := 1; i < int(n_columns); i++ { + randomness[i] = api.GetRandomValue() + } + } else { + panic("Unknown poly combine options") + } + return randomness +} + +func CombineColumn(api ecgo.API, vec_2d [][]frontend.Variable, randomness []frontend.Variable) []frontend.Variable { + n_rows := len(vec_2d) + if n_rows == 0 { + return make([]frontend.Variable, 0) + } + + n_columns := len(vec_2d[0]) + + // Do not introduce any randomness + if n_columns == 1 { + vec_combined := make([]frontend.Variable, n_rows) + for i := 0; i < n_rows; i++ { + vec_combined[i] = vec_2d[i][0] + } + return vec_combined + } + + if !IsPowerOf2(n_columns) { + panic("Consider support this") + } + + vec_return := make([]frontend.Variable, 0) + for i := 0; i < n_rows; i++ { + var v_at_row_i frontend.Variable = 0 + for j := 0; j < n_columns; j++ { + v_at_row_i = api.Add(v_at_row_i, api.Mul(randomness[j], vec_2d[i][j])) + } + vec_return = append(vec_return, v_at_row_i) + } + return vec_return +}