def test_to_from_affine(self): pt = Point(self.coords, X=Mod(0x161ff7528b899b2d0c28607ca52c5b86, self.secp128r1.curve.prime), Y=Mod(0xcf5ac8395bafeb13c02da292dded7a83, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime)) other = pt.to_affine().to_model(self.coords, self.secp128r1.curve) self.assertEqual(pt, other)
def test_to_from_affine(self): pt = Point( self.coords, X=Mod(0x161FF7528B899B2D0C28607CA52C5B86, self.secp128r1.curve.prime), Y=Mod(0xCF5AC8395BAFEB13C02DA292DDED7A83, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime), ) other = pt.to_affine().to_model(self.coords, self.secp128r1.curve) self.assertEqual(pt, other)
def scalar_mult(self, scalar: int, point: Point) -> Point: resp = self.send_cmd(SMessage.from_raw(cmd_scalar_mult(scalar, point)), self.timeout) result = resp["w"] plen = ((self.params.curve.prime.bit_length() + 7) // 8) * 2 params = {var: Mod(int(result.data[i * plen:(i + 1) * plen], 16), self.params.curve.prime) for i, var in enumerate(self.coords.variables)} return Point(self.coords, **params)
def test_equals(self): pt = Point(self.coords, X=Mod(0x4, self.secp128r1.curve.prime), Y=Mod(0x6, self.secp128r1.curve.prime), Z=Mod(2, self.secp128r1.curve.prime)) other = Point(self.coords, X=Mod(0x2, self.secp128r1.curve.prime), Y=Mod(0x3, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime)) self.assertTrue(pt.equals(other)) self.assertNotEqual(pt, other) self.assertFalse(pt.equals(2)) self.assertNotEqual(pt, 2) infty_one = InfinityPoint(self.coords) infty_other = InfinityPoint(self.coords) self.assertTrue(infty_one.equals(infty_other)) self.assertEqual(infty_one, infty_other) mont = MontgomeryModel() different = Point(mont.coordinates["xz"], X=Mod(0x64daccd2656420216545e5f65221eb, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa), Z=Mod(1, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)) self.assertFalse(pt.equals(different)) self.assertNotEqual(pt, different)
def test_to_affine(self): pt = Point(self.coords, X=Mod(0x161ff7528b899b2d0c28607ca52c5b86, self.secp128r1.curve.prime), Y=Mod(0xcf5ac8395bafeb13c02da292dded7a83, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime)) affine = pt.to_affine() self.assertIsInstance(affine.coordinate_model, AffineCoordinateModel) self.assertSetEqual(set(affine.coords.keys()), set(self.affine.variables)) self.assertEqual(affine.coords["x"], pt.coords["X"]) self.assertEqual(affine.coords["y"], pt.coords["Y"]) self.assertEqual(affine.to_affine(), affine) affine = InfinityPoint(self.coords).to_affine() self.assertIsInstance(affine, InfinityPoint)
def test_is_on_curve(self): self.assertTrue(self.secp128r1.curve.is_on_curve(self.secp128r1.curve.neutral)) pt = Point( self.secp128r1.curve.coordinate_model, X=Mod(0x161FF7528B899B2D0C28607CA52C5B86, self.secp128r1.curve.prime), Y=Mod(0xCF5AC8395BAFEB13C02DA292DDED7A83, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime), ) self.assertTrue(self.secp128r1.curve.is_on_curve(pt)) self.assertTrue(self.secp128r1.curve.is_on_curve(pt.to_affine())) other = Point( self.secp128r1.curve.coordinate_model, X=Mod(0x161FF7528B899B2D0C28607CA52C5B86, self.secp128r1.curve.prime), Y=Mod(0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime), ) self.assertFalse(self.secp128r1.curve.is_on_curve(other)) self.assertFalse(self.secp128r1.curve.is_on_curve(self.curve25519.generator))
def test_bytes(self): pt = Point(self.coords, X=Mod(0x4, self.secp128r1.curve.prime), Y=Mod(0x6, self.secp128r1.curve.prime), Z=Mod(2, self.secp128r1.curve.prime)) self.assertEqual( bytes(pt), b"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" ) self.assertEqual(bytes(InfinityPoint(self.coords)), b"\x00")
def generate(self) -> Tuple[int, Point]: resp = self.send_cmd(SMessage.from_raw(cmd_generate()), self.timeout) priv = resp["s"].data pub = resp["w"].data self.privkey = int(priv, 16) pub_len = len(pub) x = int(pub[:pub_len // 2], 16) y = int(pub[pub_len // 2:], 16) self.pubkey = Point(AffineCoordinateModel(self.model), x=Mod(x, self.params.curve.prime), y=Mod(y, self.params.curve.prime)) return self.privkey, self.pubkey
def test_to_affine(self): pt = Point( self.coords, X=Mod(0x161FF7528B899B2D0C28607CA52C5B86, self.secp128r1.curve.prime), Y=Mod(0xCF5AC8395BAFEB13C02DA292DDED7A83, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime), ) affine = pt.to_affine() self.assertIsInstance(affine.coordinate_model, AffineCoordinateModel) self.assertSetEqual(set(affine.coords.keys()), set(self.affine.variables)) self.assertEqual(affine.coords["x"], pt.coords["X"]) self.assertEqual(affine.coords["y"], pt.coords["Y"]) self.assertEqual(affine.to_affine(), affine) affine = InfinityPoint(self.coords).to_affine() self.assertIsInstance(affine, InfinityPoint)
def test_is_on_curve(self): self.assertTrue( self.secp128r1.curve.is_on_curve(self.secp128r1.curve.neutral)) pt = Point(self.secp128r1.curve.coordinate_model, X=Mod(0x161ff7528b899b2d0c28607ca52c5b86, self.secp128r1.curve.prime), Y=Mod(0xcf5ac8395bafeb13c02da292dded7a83, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime)) self.assertTrue(self.secp128r1.curve.is_on_curve(pt)) self.assertTrue(self.secp128r1.curve.is_on_curve(pt.to_affine())) other = Point(self.secp128r1.curve.coordinate_model, X=Mod(0x161ff7528b899b2d0c28607ca52c5b86, self.secp128r1.curve.prime), Y=Mod(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime)) self.assertFalse(self.secp128r1.curve.is_on_curve(other)) self.assertFalse( self.secp128r1.curve.is_on_curve(self.curve25519.generator))
def test_to_model(self): affine = Point(self.affine, x=Mod(0xabcd, self.secp128r1.curve.prime), y=Mod(0xef, self.secp128r1.curve.prime)) projective_model = self.coords other = affine.to_model(projective_model, self.secp128r1.curve) self.assertEqual(other.coordinate_model, projective_model) self.assertSetEqual(set(other.coords.keys()), set(projective_model.variables)) self.assertEqual(other.coords["X"], affine.coords["x"]) self.assertEqual(other.coords["Y"], affine.coords["y"]) self.assertEqual(other.coords["Z"], Mod(1, self.secp128r1.curve.prime)) infty = InfinityPoint(AffineCoordinateModel( self.secp128r1.curve.model)) other_infty = infty.to_model(self.coords, self.secp128r1.curve) self.assertIsInstance(other_infty, InfinityPoint) with self.assertRaises(ValueError): self.base.to_model(self.coords, self.secp128r1.curve)
def test_affine_add(self): pt = Point( AffineCoordinateModel(self.secp128r1.curve.model), x=Mod(0xEB916224EDA4FB356421773573297C15, self.secp128r1.curve.prime), y=Mod(0xBCDAF32A2C08FD4271228FEF35070848, self.secp128r1.curve.prime), ) self.assertIsNotNone(self.secp128r1.curve.affine_add(self.affine_base, pt)) added = self.secp128r1.curve.affine_add(self.affine_base, self.affine_base) doubled = self.secp128r1.curve.affine_double(self.affine_base) self.assertEqual(added, doubled) self.assertEqual( self.secp128r1.curve.affine_add(self.secp128r1.curve.neutral, pt), pt ) self.assertEqual( self.secp128r1.curve.affine_add(pt, self.secp128r1.curve.neutral), pt )
def test_assumptions(self): res = self.mdbl(self.secp128r1.curve.prime, self.secp128r1.generator, **self.secp128r1.curve.parameters) self.assertIsNotNone(res) coords = { name: value * 5 for name, value in self.secp128r1.generator.coords.items() } other = Point(self.secp128r1.generator.coordinate_model, **coords) with self.assertRaises(UnsatisfiedAssumptionError): self.mdbl(self.secp128r1.curve.prime, other, **self.secp128r1.curve.parameters) with TemporaryConfig() as cfg: cfg.ec.unsatisfied_formula_assumption_action = "ignore" pt = self.mdbl(self.secp128r1.curve.prime, other, **self.secp128r1.curve.parameters) self.assertIsNotNone(pt)
def get_pubkey(ctx: click.Context, param, value: Optional[str]) -> Point: if value is None: return None ctx.ensure_object(dict) curve: DomainParameters = ctx.obj["params"] if re.match("^04([0-9a-fA-F]{2})+$", value): value = value[2:] plen = len(value) // 2 x = int(value[:plen], 16) y = int(value[plen:], 16) elif re.match("^[0-9]+,[0-9]+$", value): xs, ys = value.split(",") x = int(xs) y = int(ys) else: raise click.BadParameter("Couldn't parse pubkey: {}.".format(value)) x = Mod(x, curve.curve.prime) y = Mod(y, curve.curve.prime) return Point(AffineCoordinateModel(curve.curve.model), x=x, y=y)
def test_symbolic(self): p = self.secp128r1.curve.prime k = FF(p) coords = self.secp128r1.curve.coordinate_model sympy_params = { key: SymbolicMod(k(int(value)), p) for key, value in self.secp128r1.curve.parameters.items() } symbolic_point = Point( coords, **{key: SymbolicMod(symbols(key), p) for key in coords.variables}) symbolic_double = self.dbl(p, symbolic_point, **sympy_params)[0] generator_double = self.dbl(p, self.secp128r1.generator, **self.secp128r1.curve.parameters)[0] for outer_var in coords.variables: symbolic_val = getattr(symbolic_double, outer_var).x generator_val = getattr(generator_double, outer_var).x for inner_var in coords.variables: symbolic_val = symbolic_val.subs( inner_var, k(getattr(self.secp128r1.generator, inner_var).x)) self.assertEqual(Mod(int(symbolic_val), p), Mod(generator_val, p))
def cmd_scalar_mult(scalar: int, point: Point) -> str: return "m" + hexlify(encode_data(None, {"s": encode_scalar(scalar), "w": encode_point(point.to_affine())})).decode()
def test_construction(self): with self.assertRaises(ValueError): Point(self.coords)
def test_equals(self): pt = Point( self.coords, X=Mod(0x4, self.secp128r1.curve.prime), Y=Mod(0x6, self.secp128r1.curve.prime), Z=Mod(2, self.secp128r1.curve.prime), ) other = Point( self.coords, X=Mod(0x2, self.secp128r1.curve.prime), Y=Mod(0x3, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime), ) third = Point( self.coords, X=Mod(0x5, self.secp128r1.curve.prime), Y=Mod(0x3, self.secp128r1.curve.prime), Z=Mod(1, self.secp128r1.curve.prime), ) self.assertTrue(pt.equals(other)) self.assertNotEqual(pt, other) self.assertFalse(pt.equals(2)) self.assertNotEqual(pt, 2) self.assertFalse(pt.equals(third)) self.assertNotEqual(pt, third) self.assertTrue(pt.equals_scaled(other)) self.assertTrue(pt.equals_affine(other)) self.assertFalse(pt.equals_scaled(third)) infty_one = InfinityPoint(self.coords) infty_other = InfinityPoint(self.coords) self.assertTrue(infty_one.equals(infty_other)) self.assertTrue(infty_one.equals_affine(infty_other)) self.assertTrue(infty_one.equals_scaled(infty_other)) self.assertEqual(infty_one, infty_other) self.assertFalse(pt.equals(infty_one)) self.assertFalse(pt.equals_affine(infty_one)) self.assertFalse(pt.equals_scaled(infty_one)) mont = MontgomeryModel() different = Point( mont.coordinates["xz"], X=Mod( 0x64DACCD2656420216545E5F65221EB, 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, ), Z=Mod(1, 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA), ) self.assertFalse(pt.equals(different)) self.assertNotEqual(pt, different)
def cmd_ecdh(pubkey: Point) -> str: return "e" + hexlify(encode_data(None, {"w": encode_point(pubkey.to_affine())})).decode()