pub(crate) enum RegisterWriter {
None,
Mul(RegisterId),
UMulH(u32),
SMulH(u32),
AddSub(RegisterId),
AddConst,
Xor(RegisterId),
XorConst,
Rotate,
}Expand description
Information about the instruction that writes to a register, from the perspective of our particular constraints here
This is conceptually similar to storing the last super::Instruction
that wrote to a register, but HashX sometimes needs information for
constraints which won’t end up in the final Instruction.
We’ve chosen the encoding to minimize the code size in writer_pair_allowed. Most pairwise comparisons can just be a register equality test.
The instructions here fall into three categories which use their own format for encoding arguments:
-
Wide Multiply, extra u32
UMulH and SMulH use an additional otherwise unused 32-bit value from the Rng when considering writer collisions.
As far as I can tell this is a bug in the original implementation but we can’t change the behavior without breaking compatibility.
The collisions are rare enough not to be a worthwhile addition to ASIC-resistance. It seems like this was a vestigial feature left over from immediate value matching features which were removed during the development of HashX, but I can’t be sure.
-
Constant source
Only considers the opcode itself, not the specific immediate value.
-
Register source
Considers the source register, collapses add/subtract into one op.
Variants§
None
Register not written yet
Mul(RegisterId)
Register source writer for super::Instruction::Mul
UMulH(u32)
Wide multiply writer for super::Instruction::UMulH
SMulH(u32)
Wide multiply writer for super::Instruction::SMulH
AddSub(RegisterId)
Register source writer for super::Instruction::AddShift
and super::Instruction::Sub
AddConst
Constant source writer for super::Instruction::AddConst
Xor(RegisterId)
Register source writer for super::Instruction::Xor
XorConst
Constant source writer for super::Instruction::XorConst
Rotate
Constant source writer for super::Instruction::Rotate