diff options
| author | J08nY | 2023-07-28 13:18:46 +0200 |
|---|---|---|
| committer | J08nY | 2023-07-28 13:18:46 +0200 |
| commit | 52da20650b3f25f11506fb5b773fd0df2a534c49 (patch) | |
| tree | 75d79a452990b667f1da8eba6a65d53e78fa4aaf | |
| parent | a20952455b5dc4a2b3166807ef1205fdfc7d911e (diff) | |
| download | pyecsca-52da20650b3f25f11506fb5b773fd0df2a534c49.tar.gz pyecsca-52da20650b3f25f11506fb5b773fd0df2a534c49.tar.zst pyecsca-52da20650b3f25f11506fb5b773fd0df2a534c49.zip | |
Move to better hash implementations.
| -rw-r--r-- | pyecsca/ec/coordinates.py | 4 | ||||
| -rw-r--r-- | pyecsca/ec/formula.py | 2 | ||||
| -rw-r--r-- | pyecsca/ec/mod.py | 2 | ||||
| -rw-r--r-- | pyecsca/ec/model.py | 2 | ||||
| -rw-r--r-- | pyecsca/ec/mult.py | 169 | ||||
| -rw-r--r-- | pyecsca/ec/point.py | 4 | ||||
| -rw-r--r-- | pyecsca/ec/signature.py | 2 | ||||
| -rw-r--r-- | pyecsca/sca/trace/trace.py | 2 |
8 files changed, 116 insertions, 71 deletions
diff --git a/pyecsca/ec/coordinates.py b/pyecsca/ec/coordinates.py index b258f2d..73ffe43 100644 --- a/pyecsca/ec/coordinates.py +++ b/pyecsca/ec/coordinates.py @@ -67,7 +67,7 @@ class AffineCoordinateModel(CoordinateModel): return self.curve_model == other.curve_model def __hash__(self): - return hash(self.curve_model) + hash(self.name) + return hash((self.curve_model, self.name)) class EFDCoordinateModel(CoordinateModel): @@ -137,4 +137,4 @@ class EFDCoordinateModel(CoordinateModel): return self.curve_model == other.curve_model and self.name == other.name def __hash__(self): - return hash(self.curve_model) + hash(self.name) + return hash((self.curve_model, self.name)) diff --git a/pyecsca/ec/formula.py b/pyecsca/ec/formula.py index 58978a7..267aba0 100644 --- a/pyecsca/ec/formula.py +++ b/pyecsca/ec/formula.py @@ -410,7 +410,7 @@ class EFDFormula(Formula): ) def __hash__(self): - return hash(self.name) + hash(self.coordinate_model) + return hash((self.coordinate_model, self.name)) @public diff --git a/pyecsca/ec/mod.py b/pyecsca/ec/mod.py index a974462..2d0893c 100644 --- a/pyecsca/ec/mod.py +++ b/pyecsca/ec/mod.py @@ -561,7 +561,7 @@ class SymbolicMod(Mod): return str(self.x) def __hash__(self): - return hash(("SymbolicMod", self.x, self.n)) + 1 + return hash(("SymbolicMod", self.x, self.n)) def __pow__(self, n) -> "SymbolicMod": try: diff --git a/pyecsca/ec/model.py b/pyecsca/ec/model.py index bea5554..55bcb18 100644 --- a/pyecsca/ec/model.py +++ b/pyecsca/ec/model.py @@ -99,7 +99,7 @@ class EFDCurveModel(CurveModel): return self._efd_name == other._efd_name def __hash__(self): - return hash(self._efd_name) + 1 + return hash(self._efd_name) def __str__(self): return f"{self.__class__.__name__.replace('Model', '')}" diff --git a/pyecsca/ec/mult.py b/pyecsca/ec/mult.py index f50d664..9b13374 100644 --- a/pyecsca/ec/mult.py +++ b/pyecsca/ec/mult.py @@ -76,14 +76,14 @@ class ScalarMultiplier(ABC): def __init__(self, short_circuit: bool = True, **formulas: Optional[Formula]): if ( - len( - { - formula.coordinate_model - for formula in formulas.values() - if formula is not None - } - ) - != 1 + len( + { + formula.coordinate_model + for formula in formulas.values() + if formula is not None + } + ) + != 1 ): raise ValueError self.short_circuit = short_circuit @@ -105,8 +105,8 @@ class ScalarMultiplier(ABC): if "dbl" not in self.formulas: raise NotImplementedError if ( - self.short_circuit - and point == self._params.curve.neutral + self.short_circuit + and point == self._params.curve.neutral ): return copy(point) return self.formulas["dbl"]( @@ -155,6 +155,11 @@ class ScalarMultiplier(ABC): self._params.curve.prime, point, **self._params.curve.parameters )[0] + def __eq__(self, other): + if not isinstance(other, ScalarMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit + def __repr__(self): return f"{self.__class__.__name__}({tuple(self.formulas.values())}, short_circuit={self.short_circuit})" @@ -170,8 +175,8 @@ class ScalarMultiplier(ABC): """ coord_model = set(self.formulas.values()).pop().coordinate_model if ( - params.curve.coordinate_model != coord_model - or point.coordinate_model != coord_model + params.curve.coordinate_model != coord_model + or point.coordinate_model != coord_model ): raise ValueError self._params = params @@ -206,18 +211,23 @@ class LTRMultiplier(ScalarMultiplier): complete: bool def __init__( - self, - add: AdditionFormula, - dbl: DoublingFormula, - scl: Optional[ScalingFormula] = None, - always: bool = False, - complete: bool = True, - short_circuit: bool = True, + self, + add: AdditionFormula, + dbl: DoublingFormula, + scl: Optional[ScalingFormula] = None, + always: bool = False, + complete: bool = True, + short_circuit: bool = True, ): super().__init__(short_circuit=short_circuit, add=add, dbl=dbl, scl=scl) self.always = always self.complete = complete + def __eq__(self, other): + if not isinstance(other, LTRMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.always == other.always and self.complete == other.complete + def multiply(self, scalar: int) -> Point: if not self._initialized: raise ValueError("ScalarMultiplier not initialized.") @@ -257,16 +267,21 @@ class RTLMultiplier(ScalarMultiplier): always: bool def __init__( - self, - add: AdditionFormula, - dbl: DoublingFormula, - scl: Optional[ScalingFormula] = None, - always: bool = False, - short_circuit: bool = True, + self, + add: AdditionFormula, + dbl: DoublingFormula, + scl: Optional[ScalingFormula] = None, + always: bool = False, + short_circuit: bool = True, ): super().__init__(short_circuit=short_circuit, add=add, dbl=dbl, scl=scl) self.always = always + def __eq__(self, other): + if not isinstance(other, RTLMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.always == other.always + def multiply(self, scalar: int) -> Point: if not self._initialized: raise ValueError("ScalarMultiplier not initialized.") @@ -303,14 +318,19 @@ class CoronMultiplier(ScalarMultiplier): optionals = {ScalingFormula} def __init__( - self, - add: AdditionFormula, - dbl: DoublingFormula, - scl: Optional[ScalingFormula] = None, - short_circuit: bool = True, + self, + add: AdditionFormula, + dbl: DoublingFormula, + scl: Optional[ScalingFormula] = None, + short_circuit: bool = True, ): super().__init__(short_circuit=short_circuit, add=add, dbl=dbl, scl=scl) + def __eq__(self, other): + if not isinstance(other, CoronMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit + def multiply(self, scalar: int) -> Point: if not self._initialized: raise ValueError("ScalarMultiplier not initialized.") @@ -338,18 +358,23 @@ class LadderMultiplier(ScalarMultiplier): complete: bool def __init__( - self, - ladd: LadderFormula, - dbl: Optional[DoublingFormula] = None, - scl: Optional[ScalingFormula] = None, - complete: bool = True, - short_circuit: bool = True, + self, + ladd: LadderFormula, + dbl: Optional[DoublingFormula] = None, + scl: Optional[ScalingFormula] = None, + complete: bool = True, + short_circuit: bool = True, ): super().__init__(short_circuit=short_circuit, ladd=ladd, dbl=dbl, scl=scl) self.complete = complete if (not complete or short_circuit) and dbl is None: raise ValueError + def __eq__(self, other): + if not isinstance(other, LadderMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.complete == other.complete + def multiply(self, scalar: int) -> Point: if not self._initialized: raise ValueError("ScalarMultiplier not initialized.") @@ -384,16 +409,21 @@ class SimpleLadderMultiplier(ScalarMultiplier): complete: bool def __init__( - self, - add: AdditionFormula, - dbl: DoublingFormula, - scl: Optional[ScalingFormula] = None, - complete: bool = True, - short_circuit: bool = True, + self, + add: AdditionFormula, + dbl: DoublingFormula, + scl: Optional[ScalingFormula] = None, + complete: bool = True, + short_circuit: bool = True, ): super().__init__(short_circuit=short_circuit, add=add, dbl=dbl, scl=scl) self.complete = complete + def __eq__(self, other): + if not isinstance(other, SimpleLadderMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.complete == other.complete + def multiply(self, scalar: int) -> Point: if not self._initialized: raise ValueError("ScalarMultiplier not initialized.") @@ -427,16 +457,21 @@ class DifferentialLadderMultiplier(ScalarMultiplier): complete: bool def __init__( - self, - dadd: DifferentialAdditionFormula, - dbl: DoublingFormula, - scl: Optional[ScalingFormula] = None, - complete: bool = True, - short_circuit: bool = True, + self, + dadd: DifferentialAdditionFormula, + dbl: DoublingFormula, + scl: Optional[ScalingFormula] = None, + complete: bool = True, + short_circuit: bool = True, ): super().__init__(short_circuit=short_circuit, dadd=dadd, dbl=dbl, scl=scl) self.complete = complete + def __eq__(self, other): + if not isinstance(other, DifferentialLadderMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.complete == other.complete + def multiply(self, scalar: int) -> Point: if not self._initialized: raise ValueError("ScalarMultiplier not initialized.") @@ -471,17 +506,22 @@ class BinaryNAFMultiplier(ScalarMultiplier): _point_neg: Point def __init__( - self, - add: AdditionFormula, - dbl: DoublingFormula, - neg: NegationFormula, - scl: Optional[ScalingFormula] = None, - short_circuit: bool = True, + self, + add: AdditionFormula, + dbl: DoublingFormula, + neg: NegationFormula, + scl: Optional[ScalingFormula] = None, + short_circuit: bool = True, ): super().__init__( short_circuit=short_circuit, add=add, dbl=dbl, neg=neg, scl=scl ) + def __eq__(self, other): + if not isinstance(other, BinaryNAFMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit + def init(self, params: DomainParameters, point: Point): with PrecomputationAction(params, point): super().init(params, point) @@ -518,14 +558,14 @@ class WindowNAFMultiplier(ScalarMultiplier): width: int def __init__( - self, - add: AdditionFormula, - dbl: DoublingFormula, - neg: NegationFormula, - width: int, - scl: Optional[ScalingFormula] = None, - precompute_negation: bool = False, - short_circuit: bool = True, + self, + add: AdditionFormula, + dbl: DoublingFormula, + neg: NegationFormula, + width: int, + scl: Optional[ScalingFormula] = None, + precompute_negation: bool = False, + short_circuit: bool = True, ): super().__init__( short_circuit=short_circuit, add=add, dbl=dbl, neg=neg, scl=scl @@ -533,6 +573,11 @@ class WindowNAFMultiplier(ScalarMultiplier): self.width = width self.precompute_negation = precompute_negation + def __eq__(self, other): + if not isinstance(other, WindowNAFMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.width == other.width and self.precompute_negation == other.precompute_negation + def init(self, params: DomainParameters, point: Point): with PrecomputationAction(params, point): super().init(params, point) diff --git a/pyecsca/ec/point.py b/pyecsca/ec/point.py index c4da538..b63c924 100644 --- a/pyecsca/ec/point.py +++ b/pyecsca/ec/point.py @@ -203,7 +203,7 @@ class Point: return self.coords == other.coords def __hash__(self): - return hash((self.coordinate_model.name, tuple(self.coords.keys()), tuple(self.coords.values()))) + 13 + return hash((self.coordinate_model, tuple(self.coords.keys()), tuple(self.coords.values()))) def __str__(self): args = ", ".join([f"{key}={val}" for key, val in self.coords.items()]) @@ -254,7 +254,7 @@ class InfinityPoint(Point): return self.coordinate_model == other.coordinate_model def __hash__(self): - return hash(self.coordinate_model.name) + 13 + return hash((self.coordinate_model, 0)) def __str__(self): return "Infinity" diff --git a/pyecsca/ec/signature.py b/pyecsca/ec/signature.py index a65adbc..54ca010 100644 --- a/pyecsca/ec/signature.py +++ b/pyecsca/ec/signature.py @@ -43,7 +43,7 @@ class SignatureResult: return self.r == other.r and self.s == other.s def __hash__(self): - return hash((self.r, self.s)) + 11 + return hash((self.r, self.s)) def __str__(self): return f"(r={self.r}, s={self.s})" diff --git a/pyecsca/sca/trace/trace.py b/pyecsca/sca/trace/trace.py index 367125b..4388643 100644 --- a/pyecsca/sca/trace/trace.py +++ b/pyecsca/sca/trace/trace.py @@ -78,7 +78,7 @@ class Trace: def __hash__(self): # This will have collisions, but those can be sorted out by the equality check above. - return hash(str(self.samples)) + hash(self.meta) + return hash((str(self.samples), tuple(self.meta.items()))) def with_samples(self, samples: ndarray) -> "Trace": """ |
