cascada.algebraic.opmodel module
Manipulate algebraic models of bit-vector operations.
Represent algebraic models of bit-vector operations. |
|
Represent the |
|
Represent the |
|
Represent the |
|
Represent the |
- class cascada.algebraic.opmodel.OpModel(input_prop)[source]
Bases:
cascada.abstractproperty.opmodel.OpModel
Represent algebraic models of bit-vector operations.
A (bit-vector) algebraic model of a bit-vector
Operation
\(f\) is a set of bit-vector constraints that models the propagation probability of value properties of \(f\). SeeValue
.An algebraic model is defined for a type of
Value
, such asBitValue
orWordValue
.This class is not meant to be instantiated but to provide a base class for creating algebraic models.
Note
For all algebraic models, the
pr_one_constraint
method is equivalent to thevalidity_constraint
method, and the weight of a valid propagation is alwaysConstant(0, 1)
. This class implements the methodspr_one_constraint, bv_weight, max_weight, weight_width, decimal_weight, num_frac_bits
anderror
, and subclasses only need to implementvalidity_constraint
.- val_type
the type of
Value
(alias ofabstractproperty.opmodel.OpModel.prop_type
).
- input_val
a list containing the
Value
of each bit-vector operand (alias ofabstractproperty.opmodel.OpModel.input_prop
).
- pr_one_constraint(output_val)[source]
Return the probability-one constraint for a given output
Property
.Return the constraint that evaluates to True if the input
Property
propagates to the given outputProperty
with probability one.This method returns a bit-vector expression that depends on the input property
OpModel.input_prop
and the output propertyoutput_prop
and it is True if and only if the input property propagates to the output property with probability 1.If both the input and output properties are constant values, this method returns the
Constant
0b1
or0b0
depending on whether the corresponding propagation has probability 1. Otherwise, this method returns a bit-vectorTerm
containing the input and output properties asVariable
objects.
- bv_weight(output_val)[source]
Return the bit-vector weight for a given output
Property
.The bit-vector weight is a bit-vector expression that depends on the input property
OpModel.input_prop
and the output propertyoutput_prop
. This bit-vector function represents an approximation of the negative binary logarithm (weight) of the probability of the input property propagating to the output property.Note
This method is optional and subclasses of
OpModel
don’t need to implement it (as opposed toOpModel.weight_constraint
).It is assumed that the corresponding propagation has non-zero probability.
If the input and output properties are constant values, this method returns a
Constant
of bit-sizeweight_width
denoting the weight of the valid propagation. Otherwise, this method returns a bit-vectorTerm
containing the input and output properties asVariable
objects.
- max_weight()[source]
Return the maximum value the weight variable can achieve in
OpModel.weight_constraint
.
- weight_width()[source]
Return the width of the weight variable used
OpModel.weight_constraint
.
- decimal_weight(output_val)[source]
Return the
decimal.Decimal
weight for a given constant outputProperty
.This method returns, as a decimal number, the weight (negative binary logarithm) of the probability of the input property propagating to the output property.
This method only works when the input property and the output property are constant values, but provides a better approximation than the bit-vector weight from
OpModel.weight_constraint
.
- num_frac_bits()[source]
Return the number of fractional bits used in the weight variable of
OpModel.weight_constraint
.If the number of fractional bits is
k
, then the bit-vector weight variablew
ofOpModel.weight_constraint
represents the number2^{-k} * bv2int(w)
. In particular, ifk == 0
, thenw
represents an integer number. Otherwise, thek
least significant bits ofw
denote the fractional part of the number represented byw
.
- error()[source]
Return the maximum difference between
OpModel.weight_constraint
and the exact weight.The exact weight is exact value (without error) of the negative binary logarithm (weight) of the propagation probability of \((\alpha, \beta)\).
Note
The exact weight can be computed in
TestOpModelGeneric.get_empirical_weight_slow
.This method returns an upper bound (in absolute value) of the maximum difference (over all input and output properties) between the bit-vector weight from
OpModel.weight_constraint
and the exact weight.Note that the exact weight might still differ from
decimal_weight
.
- class cascada.algebraic.opmodel.BitModelId(input_prop)[source]
Bases:
cascada.abstractproperty.opmodel.ModelIdentity
,cascada.algebraic.opmodel.OpModel
Represent the
BitValue
algebraic.opmodel.OpModel
ofBvIdentity
.See also
ModelIdentity
.>>> from cascada.bitvector.core import Constant, Variable >>> from cascada.algebraic.value import BitValue >>> from cascada.algebraic.opmodel import BitModelId >>> alpha, beta = BitValue(Variable("a", 4)), BitValue(Variable("b", 4)) >>> f = BitModelId(alpha) >>> print(f.vrepr()) BitModelId(BitValue(Variable('a', width=4))) >>> f.validity_constraint(beta) ((a[0]) == (b[0])) & ((a[1]) == (b[1])) & ((a[2]) == (b[2])) & ((a[3]) == (b[3])) >>> f.max_weight(), f.weight_width(), f.error(), f.num_frac_bits() (0, 1, 0, 0)
- val_type
alias of
cascada.algebraic.value.BitValue
- validity_constraint(output_val)[source]
Return the validity constraint for a given output
Property
.The validity constraint is a bit-vector expression that depends on the input property
OpModel.input_prop
and the output propertyoutput_prop
and it is True if and only if the input property propagates to the output property with non-zero probability.If both the input and output properties are constant values, this method returns the
Constant
0b1
or0b0
depending on whether the corresponding propagation has non-zero probability. Otherwise, this method returns a bit-vectorTerm
containing the input and output properties asVariable
objects.
- class cascada.algebraic.opmodel.WordModelId(input_prop)[source]
Bases:
cascada.abstractproperty.opmodel.ModelIdentity
,cascada.algebraic.opmodel.OpModel
Represent the
WordValue
algebraic.opmodel.OpModel
ofBvIdentity
.See also
ModelIdentity
.>>> from cascada.bitvector.core import Constant, Variable >>> from cascada.algebraic.value import WordValue >>> from cascada.algebraic.opmodel import WordModelId >>> alpha, beta = WordValue(Variable("a", 4)), WordValue(Variable("b", 4)) >>> f = WordModelId(alpha) >>> print(f.vrepr()) WordModelId(WordValue(Variable('a', width=4))) >>> f.validity_constraint(beta) a == b >>> f.max_weight(), f.weight_width(), f.error(), f.num_frac_bits() (0, 1, 0, 0)
- val_type
alias of
cascada.algebraic.value.WordValue
- class cascada.algebraic.opmodel.BitModelBvAdd(input_prop)[source]
Bases:
cascada.algebraic.opmodel.OpModel
Represent the
BitValue
algebraic.opmodel.OpModel
ofBvAdd
.>>> from cascada.bitvector.core import Constant, Variable >>> from cascada.algebraic.value import BitValue >>> from cascada.algebraic.opmodel import BitModelBvAdd >>> alpha = BitValue(Variable("a", 4)), BitValue(Variable("b", 4)) >>> f = BitModelBvAdd(alpha) >>> print(f.vrepr()) BitModelBvAdd([BitValue(Variable('a', width=4)), BitValue(Variable('b', width=4))]) >>> f.max_weight(), f.weight_width(), f.error(), f.num_frac_bits() (0, 1, 0, 0)
- val_type
alias of
cascada.algebraic.value.BitValue
- op
alias of
cascada.bitvector.operation.BvAdd
- validity_constraint(output_val)[source]
Return the validity constraint for a given
BitValue
output.This model is based on the fact that the \(n\)-bit modular addition \(x \boxplus y = z\) has the following implicit function \(x \oplus y \oplus z \oplus Q(x \oplus z, y \oplus z)\) where \(Q(x, y) = (0, x_0 \wedge y_0, (x_0 \wedge y_0) \oplus (x_1 \wedge y_1), \dots, (x_0 \wedge y_0) \oplus (x_1 \wedge y_1) \oplus \dots \oplus (x_{n-2} \wedge y_{n-2}))\)
Source: Implicit White-Box Implementations: White-Boxing ARX Ciphers.
>>> from cascada.bitvector.core import Constant, Variable >>> from cascada.algebraic.value import BitValue >>> from cascada.algebraic.opmodel import BitModelBvAdd >>> alpha = BitValue(Constant(0, 3)), BitValue(Constant(0, 3)) >>> f = BitModelBvAdd(alpha) >>> beta = BitValue(Constant(0, 3)) >>> f.validity_constraint(beta) 0b1 >>> a0, a1, b = Variable("a0", 3), Variable("a1", 3), Variable("b", 3) >>> alpha = BitValue(a0), BitValue(a1) >>> f = BitModelBvAdd(alpha) >>> beta = BitValue(b) >>> result = f.validity_constraint(beta) >>> result (0b0 == ((a0[0]) ^ (a1[0]) ^ (b[0]))) & (0b0 == ((a0[1]) ^ (a1[1]) ^ (b[1]) ^ (((a0[0]) ^ (b[0])) & ((a1[0]) ^ (b[0]))))) & (0b0 == ((a0[2]) ^ (a1[2]) ^ (b[2]) ^ (((a0[0]) ^ (b[0])) & ((a1[0]) ^ (b[0]))) ^ (((a0[1]) ^ (b[1])) & ((a1[1]) ^ (b[1]))))) >>> result.xreplace({a0: Constant(0, 3), a1: Constant(0, 3), b: Constant(0, 3)}) 0b1 >>> a1 = Constant(0, 3) >>> alpha = BitValue(a0), BitValue(a1) >>> f = BitModelBvAdd(alpha) >>> beta = BitValue(b) >>> result = f.validity_constraint(beta) >>> result (0b0 == ((a0[0]) ^ (b[0]))) & (0b0 == ((a0[1]) ^ (b[1]) ^ (((a0[0]) ^ (b[0])) & (b[0])))) & (0b0 == ((a0[2]) ^ (b[2]) ^ (((a0[0]) ^ (b[0])) & (b[0])) ^ (((a0[1]) ^ (b[1])) & (b[1]))))
See
OpModel.validity_constraint
for more information.
- class cascada.algebraic.opmodel.BitModelBvSub(input_prop)[source]
Bases:
cascada.algebraic.opmodel.OpModel
Represent the
BitValue
algebraic.opmodel.OpModel
ofBvSub
.>>> from cascada.bitvector.core import Constant, Variable >>> from cascada.algebraic.value import BitValue >>> from cascada.algebraic.opmodel import BitModelBvSub >>> alpha = BitValue(Variable("a", 4)), BitValue(Variable("b", 4)) >>> f = BitModelBvSub(alpha) >>> print(f.vrepr()) BitModelBvSub([BitValue(Variable('a', width=4)), BitValue(Variable('b', width=4))]) >>> f.max_weight(), f.weight_width(), f.error(), f.num_frac_bits() (0, 1, 0, 0)
The algebraic model of the modular substraction is based on
BitModelBvAdd
since~(x - y) == ~x + y
.- val_type
alias of
cascada.algebraic.value.BitValue
- op
alias of
cascada.bitvector.operation.BvSub
- validity_constraint(output_val)[source]
Return the validity constraint for a given
BitValue
output.>>> from cascada.bitvector.core import Constant, Variable >>> from cascada.algebraic.value import BitValue >>> from cascada.algebraic.opmodel import BitModelBvSub >>> alpha = BitValue(Constant(0, 3)), BitValue(Constant(0, 3)) >>> f = BitModelBvSub(alpha) >>> beta = BitValue(Constant(0, 3)) >>> f.validity_constraint(beta) 0b1 >>> a0, a1, b = Variable("a0", 3), Variable("a1", 3), Variable("b", 3) >>> alpha = BitValue(a0), BitValue(a1) >>> f = BitModelBvSub(alpha) >>> beta = BitValue(b) >>> result = f.validity_constraint(beta) >>> result (0b0 == (~(a0[0]) ^ (a1[0]) ^ ~(b[0]))) & (0b0 == (~(a0[1]) ^ (a1[1]) ^ ~(b[1]) ^ ((~(a0[0]) ^ ~(b[0])) & ((a1[0]) ^ ~(b[0]))))) & (0b0 == (~(a0[2]) ^ (a1[2]) ^ ~(b[2]) ^ ((~(a0[0]) ^ ~(b[0])) & ((a1[0]) ^ ~(b[0]))) ^ ((~(a0[1]) ^ ~(b[1])) & ((a1[1]) ^ ~(b[1]))))) >>> result.xreplace({a0: Constant(0, 3), a1: Constant(0, 3), b: Constant(0, 3)}) 0b1 >>> a1 = Constant(0, 3) >>> alpha = BitValue(a0), BitValue(a1) >>> f = BitModelBvSub(alpha) >>> beta = BitValue(b) >>> result = f.validity_constraint(beta) >>> result (0b0 == (~(a0[0]) ^ ~(b[0]))) & (0b0 == (~(a0[1]) ^ ~(b[1]) ^ ((~(a0[0]) ^ ~(b[0])) & ~(b[0])))) & (0b0 == (~(a0[2]) ^ ~(b[2]) ^ ((~(a0[0]) ^ ~(b[0])) & ~(b[0])) ^ ((~(a0[1]) ^ ~(b[1])) & ~(b[1]))))
See
OpModel.validity_constraint
for more information.