@@ -13,7 +13,7 @@ class EqualityOperator < CryptoOperator
super(
inputs: [input],
outputs: [output],
constraint: Equality.new(input,output),
constraints: [Equality.new(input,output)],
)
end
end
...
...
@@ -27,10 +27,10 @@ class XorOperator < CryptoOperator
super(
inputs: inputs,
outputs: [output],
constraint: Equality.new(
constraints: [Equality.new(
Xor.new(*inputs),
output
),
)],
)
end
end
...
...
@@ -45,32 +45,59 @@ class SOperator < CryptoOperator
super(
inputs: [input],
outputs: [output],
constraint: TableConstraint.new(
constraints: [TableConstraint.new(
[input,output],
s_array.length.times.map{|i|[i,s_array[i]]}
),
)],
)
end
end
## MixColumns operator
classMixColumnsOperator<CryptoOperator
##
# @params inputs [Vec<u8>] 4 byte input
# @params outputs [Vec<u8>] 4 byte output
# @params m [Vec<Vec<u8>>] mixcolumns matrix
definitialize(inputs,outputs,m)
raise"MixColumnsOperator: matrix dimensions should be of the same size of the input (current y size: #{m.length})"unlessinputs.length==m.length
raise"MixColumnsOperator: matrix dimensions should be of the same size of the input (current x size: #{m.first.length})"unlessinputs.length==m.first.length
raise"MixColumnsOperator: output dimensions should be of the same size of the input (current size: #{outputs.length})"unlessinputs.length==outputs.length
@m=m
super(
inputs: inputs,
outputs: outputs,
constraint: Equality.new(
# TODO(all) add And or ForEach constraint to "mix" all inputs and outputs
)
)
super(inputs:inputs,outputs:outputs)
##
# @params inputs [Vec<variable>] 4 byte input
# @params outputs [Vec<variable>] 4 byte output
# @params m [Vec<u8>] mixcolumns matrix vector
definitialize(inputs,outputs,m)
raise"MixColumnsOperator: matrix dimensions should be of the same size of the input (current y size: #{m.length})"unlessinputs.length==m.length
raise"MixColumnsOperator: matrix dimensions should be of the same size of the input (current x size: #{m..first.length})"unlessinputs.length==m.first.length
raise"MixColumnsOperator: output dimensions should be of the same size of the input (current size: #{outputs.length})"unlessinputs.length==outputs.length
@m=m
constraints=[]
inputs.length.timesdo|i|# add a constraint per output
constraints.push(Equality.new(
Xor.new(*inputs.length.times.map{|j|
galois_field_multiply(inputs[j],m[i][j])
}),
outputs[i]
))
end
super(
inputs: inputs,
outputs: outputs,
constraints: constraints,
)
end
##
# @param e [Expression] value to multiply by the matrix element
# @param m [u8] value used to multiply
# @return [Expression] that multiplies e by m in the galois field
defgalois_field_multiply(e,m)
ifm==0
return0
elsifm==1
returne
elsifm==2
returnModulo.new(Mult.new(e,2),256)
elsifm==3
returnModulo.new(
Xor.new(Mult.new(e,2),e),
256
)
else
raise"galois_field_multiply: m=#{m} not supported yet (for now, it should be <= 3)"