feat!: add support for u1 in the avm circuit & witgen#8570
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
876c708 to
34a7a3a
Compare
34a7a3a to
8d63104
Compare
8d63104 to
f45b6d5
Compare
f45b6d5 to
1f4b7b9
Compare
cbdd5f0 to
e2ddcf1
Compare
| let num_bits = val.num_bits(); | ||
| if num_bits < 8 { | ||
| if num_bits <= 8 { | ||
| 8 | ||
| } else if num_bits < 16 { | ||
| } else if num_bits <= 16 { | ||
| 16 | ||
| } else if num_bits < 32 { | ||
| } else if num_bits <= 32 { | ||
| 32 | ||
| } else if num_bits < 64 { | ||
| } else if num_bits <= 64 { | ||
| 64 | ||
| } else if num_bits < 128 { | ||
| } else if num_bits <= 128 { | ||
| 128 |
There was a problem hiding this comment.
This was just a bug
| { | ||
| std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD | ||
| "00" // Indirect flag | ||
| "01" // U8 | ||
| std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD | ||
| "00" // Indirect flag | ||
| + to_hex(AvmMemoryTag::U8) + | ||
| "0007" // addr a 7 |
There was a problem hiding this comment.
I changed this across the whole file so that we aren't using magic numbers
e2ddcf1 to
c34a75b
Compare
| template <typename T> | ||
| requires(std::unsigned_integral<T>) | ||
| std::string to_hex(T value) | ||
| { | ||
| std::ostringstream stream; | ||
| auto num_bytes = static_cast<uint64_t>(sizeof(T)); | ||
| auto mask = static_cast<uint64_t>((static_cast<uint128_t>(1) << (num_bytes * 8)) - 1); | ||
| auto padding = static_cast<int>(num_bytes * 2); | ||
| stream << std::setfill('0') << std::setw(padding) << std::hex << (value & mask); | ||
| return stream.str(); | ||
| } | ||
|
|
||
| std::string to_hex(bb::avm_trace::AvmMemoryTag tag); |
There was a problem hiding this comment.
Moved from opcode.hpp because it's now useful for memory tags too
54870c3 to
6d7d35f
Compare
| type IntegralClass = typeof Uint1 | typeof Uint8 | typeof Uint16 | typeof Uint32 | typeof Uint64 | typeof Uint128; | ||
|
|
||
| describe.each([Uint1])('Integral Types (U1 only)', (clsValue: IntegralClass) => { | ||
| describe(`${clsValue.name}`, () => { | ||
| it(`Should construct a new ${clsValue.name} from a number`, () => { | ||
| const x = new clsValue(1); | ||
| expect(x.toBigInt()).toStrictEqual(1n); | ||
| }); |
There was a problem hiding this comment.
Not sure it's worth spending the effort at this time to combine this with the test cases for non-U1 types since they use values other than 0 and 1.
| public toBuffer(): Buffer { | ||
| if (bits < 8) { | ||
| return toBufferBE(this.n, 1); | ||
| } | ||
| return toBufferBE(this.n, bits / 8); | ||
| } |
There was a problem hiding this comment.
Still need a whole byte for a Uint1
6d7d35f to
62c53fc
Compare
e6741b3 to
81d6194
Compare
| uint32_t dst_offset, | ||
| uint32_t radix_offset, | ||
| uint32_t num_limbs, | ||
| uint8_t output_bits) |
There was a problem hiding this comment.
Is there a reason this isn't of type bool?
There was a problem hiding this comment.
Just would be a one-off I think. Wasn't sure if I should leave it as a byte which is what it is in the wire format for the instruction. Instruction wire format operates in bytes.
But I could certainly change this to be type bool
|
Hey all, this shouldn't cause a problem for noir syncing. Using an older version of bb with the new brillig format will result in it misinterpreting the memory address as an immediate value but as bb doesn't use the brillig for anything, it won't cause any unexpected behaviour. |
jeanmon
left a comment
There was a problem hiding this comment.
LGTM! Very good job! Check my comments.
| // This holds the product over the integers | ||
| pol PRODUCT = a_lo * b_lo + LIMB_BITS_POW * partial_prod_lo + MAX_BITS_POW * (partial_prod_hi + a_hi * b_hi); | ||
| // (u1 multiplication only cares about a_lo and b_lo) | ||
| pol PRODUCT = a_lo * b_lo + (1 - u1_tag) * (LIMB_BITS_POW * partial_prod_lo + MAX_BITS_POW * (partial_prod_hi + a_hi * b_hi)); |
There was a problem hiding this comment.
We should not need the exception for u1, ie., the term (1 - u1_tag) can be removed I think.
There was a problem hiding this comment.
Without that exception for u1, I believe a_hi and b_hi are underconstrained since LIMB_BITS_POW is 0. Or am I wrong?
5066620 to
e4c8a5b
Compare
e4c8a5b to
cc3d469
Compare

output_bitsflag (is output in bits mode).radixoperand to be a memory offset instead of an immediate.radix_offset's read is not constrained due to #8603