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.OpModelRepresent 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 asBitValueorWordValue.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_constraintmethod is equivalent to thevalidity_constraintmethod, 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_bitsanderror, 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
Valueof 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
Propertypropagates to the given outputPropertywith probability one.This method returns a bit-vector expression that depends on the input property
OpModel.input_propand the output propertyoutput_propand 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
Constant0b1or0b0depending on whether the corresponding propagation has probability 1. Otherwise, this method returns a bit-vectorTermcontaining the input and output properties asVariableobjects.
- 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_propand 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
OpModeldon’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
Constantof bit-sizeweight_widthdenoting the weight of the valid propagation. Otherwise, this method returns a bit-vectorTermcontaining the input and output properties asVariableobjects.
- 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.Decimalweight 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 variablewofOpModel.weight_constraintrepresents the number2^{-k} * bv2int(w). In particular, ifk == 0, thenwrepresents an integer number. Otherwise, thekleast significant bits ofwdenote the fractional part of the number represented byw.
- error()[source]
Return the maximum difference between
OpModel.weight_constraintand 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_constraintand 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.OpModelRepresent the
BitValuealgebraic.opmodel.OpModelofBvIdentity.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_propand the output propertyoutput_propand 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
Constant0b1or0b0depending on whether the corresponding propagation has non-zero probability. Otherwise, this method returns a bit-vectorTermcontaining the input and output properties asVariableobjects.
- class cascada.algebraic.opmodel.WordModelId(input_prop)[source]
Bases:
cascada.abstractproperty.opmodel.ModelIdentity,cascada.algebraic.opmodel.OpModelRepresent the
WordValuealgebraic.opmodel.OpModelofBvIdentity.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.OpModelRepresent the
BitValuealgebraic.opmodel.OpModelofBvAdd.>>> 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
BitValueoutput.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_constraintfor more information.
- class cascada.algebraic.opmodel.BitModelBvSub(input_prop)[source]
Bases:
cascada.algebraic.opmodel.OpModelRepresent the
BitValuealgebraic.opmodel.OpModelofBvSub.>>> 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
BitModelBvAddsince~(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
BitValueoutput.>>> 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_constraintfor more information.