Lookup2 performs a 2-bit lookup based on the given bits and values.
(b0, b1 frontend.Variable, i0, i1, i2, i3 frontend.Variable)
| 309 | |
| 310 | // Lookup2 performs a 2-bit lookup based on the given bits and values. |
| 311 | func (builder *builder) Lookup2(b0, b1 frontend.Variable, i0, i1, i2, i3 frontend.Variable) frontend.Variable { |
| 312 | vars := []frontend.Variable{b0, b1, i0, i1, i2, i3} |
| 313 | s0, s1 := vars[0], vars[1] |
| 314 | in0, in1, in2, in3 := vars[2], vars[3], vars[4], vars[5] |
| 315 | |
| 316 | // ensure that bits are actually bits. Adds no constraints if the variables |
| 317 | // are already constrained. |
| 318 | builder.AssertIsBoolean(s0) |
| 319 | builder.AssertIsBoolean(s1) |
| 320 | |
| 321 | // two-bit lookup for the general case can be done with three constraints as |
| 322 | // following: |
| 323 | // (1) (in3 - in2 - in1 + in0) * s1 = tmp1 - in1 + in0 |
| 324 | // (2) tmp1 * s0 = tmp2 |
| 325 | // (3) (in2 - in0) * s1 = RES - tmp2 - in0 |
| 326 | // the variables tmp1 and tmp2 are new internal variables and the variables |
| 327 | // RES will be the returned result |
| 328 | |
| 329 | tmp1 := builder.Add(in3, in0) |
| 330 | tmp1 = builder.Sub(tmp1, in2, in1) |
| 331 | tmp1 = builder.Mul(tmp1, s1) |
| 332 | tmp1 = builder.Add(tmp1, in1) |
| 333 | tmp1 = builder.Sub(tmp1, in0) // (1) tmp1 = s1 * (in3 - in2 - in1 + in0) + in1 - in0 |
| 334 | tmp2 := builder.Mul(tmp1, s0) // (2) tmp2 = tmp1 * s0 |
| 335 | res := builder.Sub(in2, in0) |
| 336 | res = builder.Mul(res, s1) |
| 337 | res = builder.Add(res, tmp2, in0) // (3) res = (v2 - v0) * s1 + tmp2 + in0 |
| 338 | return res |
| 339 | } |
| 340 | |
| 341 | // IsZero returns 1 if the given variable is zero, otherwise returns 0. |
| 342 | func (builder *builder) IsZero(i1 frontend.Variable) frontend.Variable { |
nothing calls this directly
no test coverage detected