def bip32_xpub_from_xprv(xprv: bytes) -> bytes: """Neutered Derivation (ND) Computation of the extended public key corresponding to an extended private key (“neutered” as it removes the ability to sign transactions) """ xprv = b58decode_check(xprv, 78) assert xprv[45] == 0, "extended key is not a private one" i = PRIVATE.index(xprv[:4]) # serialization data xpub = PUBLIC[i] # version # unchanged serialization data xpub += xprv[4:5] # depth xpub += xprv[5:9] # parent pubkey fingerprint xpub += xprv[9:13] # child index xpub += xprv[13:45] # chain code p = xprv[46:] P = pointMultiply(ec, p, ec.G) xpub += bytes_from_Point(ec, P, True) # public key return b58encode_check(xpub)
def test_all_curves(self): for ec in allcurves: # the infinity point is represented by None self.assertEqual(ec.pointMultiply(0, ec.G), None) self.assertEqual(pointMultiply(ec, 0, ec.G), None) self.assertEqual(ec.pointMultiply(1, ec.G), ec.G) self.assertEqual(pointMultiply(ec, 1, ec.G), ec.G) Gy_odd = ec.y(ec.G[0], True) self.assertEqual(Gy_odd % 2, 1) Gy_even = ec.y(ec.G[0], False) self.assertEqual(Gy_even % 2, 0) self.assertTrue(ec.G[1] in (Gy_odd, Gy_even)) Gbytes = bytes_from_Point(ec, ec.G, True) Gbytes = bytes_from_Point(ec, Gbytes, True) G2 = tuple_from_Point(ec, Gbytes) G2 = tuple_from_Point(ec, G2) self.assertEqual(ec.G, G2) Gbytes = bytes_from_Point(ec, ec.G, False) Gbytes = bytes_from_Point(ec, Gbytes, False) G2 = tuple_from_Point(ec, Gbytes) G2 = tuple_from_Point(ec, G2) self.assertEqual(ec.G, G2) P = ec.pointAdd(None, ec.G) self.assertEqual(P, ec.G) P = ec.pointAdd(ec.G, None) self.assertEqual(P, ec.G) P = ec.pointAdd(None, None) self.assertEqual(P, None) P = pointAdd(ec, None, ec.G) self.assertEqual(P, ec.G) P = pointAdd(ec, ec.G, None) self.assertEqual(P, ec.G) P = pointAdd(ec, None, None) self.assertEqual(P, None) P = ec.pointDouble(ec.G) self.assertEqual(P, ec.pointMultiply(2, ec.G)) P = pointDouble(ec, ec.G) self.assertEqual(P, pointMultiply(ec, 2, ec.G)) P = ec.pointAdd(ec.G, ec.G) self.assertEqual(P, ec.pointMultiply(2, ec.G)) P = pointAdd(ec, ec.G, ec.G) self.assertEqual(P, pointMultiply(ec, 2, ec.G)) P = ec.pointMultiply(ec.order - 1, ec.G) self.assertEqual(ec.pointAdd(P, ec.G), None) self.assertEqual(ec.pointMultiply(ec.order, ec.G), None) P = pointMultiply(ec, ec.order - 1, ec.G) self.assertEqual(pointAdd(ec, P, ec.G), None) self.assertEqual(pointMultiply(ec, ec.order, ec.G), None) self.assertEqual(ec.pointMultiply(0, None), None) self.assertEqual(ec.pointMultiply(1, None), None) self.assertEqual(ec.pointMultiply(25, None), None) self.assertEqual(pointMultiply(ec, 0, None), None) self.assertEqual(pointMultiply(ec, 1, None), None) self.assertEqual(pointMultiply(ec, 25, None), None) ec2 = eval(repr(ec)) self.assertEqual(str(ec2), str(ec2)) if (ec.order % 2 == 0): P = ec.pointMultiply(ec.order // 2, ec.G) self.assertEqual(P[1], 0) self.assertEqual(ec.pointDouble(P), None) P = pointMultiply(ec, ec.order // 2, ec.G) self.assertEqual(P[1], 0) self.assertEqual(pointDouble(ec, P), None)
def pubkey_from_prvkey(prvkey: PrivateKey, compressed: bool = True) -> bytes: """Private key to (bytes) public key""" P = pointMultiply(ec, prvkey, ec.G) return bytes_from_Point(ec, P, compressed)
def pedersen_commit(ec: EllipticCurve, r: Scalar, v: Scalar) -> Point: rG = pointMultiply(ec, r, ec.G) vH = pointMultiply(ec, v, secondGenerator(ec)) return pointAdd(ec, rG, vH)