from app.api.resources import Xpub_To_Public_Key
from app.api.resources import Xpub_Verify
from app.api.resources import Xprv_Sign
+from app.api.resources import Xprv_To_Xpub
blueprint = Blueprint('api', __name__, url_prefix='/api/v1')
api = Api(blueprint)
api.add_resource(Xprv_To_Expanded_Private_Key, '/xprv_to_expanded_private_key')
api.add_resource(Xpub_To_Public_Key, '/xpub_to_public_key')
api.add_resource(Xpub_Verify, '/xpub_verify')
-api.add_resource(Xprv_Sign, '/xprv_sign')
\ No newline at end of file
+api.add_resource(Xprv_Sign, '/xprv_sign')
+api.add_resource(Xprv_To_Xpub, '/xprv_to_xpub')
\ No newline at end of file
from app.model.key import xpub_to_public_key
from app.model.key import xpub_verify
from app.model.key import xprv_sign
+from app.model.key import xprv_to_xpub
parser = reqparse.RequestParser()
parser.add_argument('private_key_str', type=str)
xprv = args.get('xprv_str')
message = args.get('message_str')
signature = xprv_sign(xprv, message)
- return signature
\ No newline at end of file
+ return signature
+
+class Xprv_To_Xpub(Resource):
+
+ def post(self):
+ args = parser.parse_args()
+ xprv = args.get('xprv_str')
+ xpub = xprv_to_xpub(xprv)
+ return xpub
\ No newline at end of file
# private_key = ed25519.SigningKey(bytes.fromhex(private_key_str))
# public_key_str = private_key.get_verifying_key().to_ascii(encoding='hex').decode()
-############# ERR!!!!!!!!!########################
-############# ERR!!!!!!!!!########################
-############# ERR!!!!!!!!!########################
-############# ERR!!!!!!!!!########################
+
# xprv_to_xpub derives new xpub from xprv
# xprv length is 64 bytes.
# xpub length is 64 bytes.
# You can verify or get more test data from: https://gist.github.com/zcc0721/d872a219fa91621d60357278bc62a512
+# PLEASE ATTENTION:
+# xprv_bytes = bytes.fromhex(xprv_str)
+# xprv_bytes[31] <= 127
+# This is the precondition. Please ref: https://github.com/bytom/bytom/blob/dev/crypto/ed25519/internal/edwards25519/edwards25519.go#L958-L963
# test data 1:
# xprv_str: c003f4bcccf9ad6f05ad2c84fa5ff98430eb8e73de5de232bc29334c7d074759d513bc370335cac51d77f0be5dfe84de024cfee562530b4d873b5f5e2ff4f57c
# xpub_str: 1b0541a7664cee929edb54d9ef21996b90546918a920a77e1cd6015d97c56563d513bc370335cac51d77f0be5dfe84de024cfee562530b4d873b5f5e2ff4f57c
# test data 2:
-# xprv_str: 4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a
-# xpub_str: bf852a7c36fe9c90c5fd2066c0407148f6e9ccf16324eb9f5cc01d9a2afe28957b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a
+# xprv_str: 36667587de27eec684fc4b222276f22a24d9a82e947ee0119148bedd4dec461dd4e1b1d95dfb0f78896677ea1026af7510b41fabd3bd5771311c0cb6968337b2
+# xpub_str: ef0b3a8b0d66523d88f214900101ddb08a2a2a6db28bd8002e5995c1f1cbbc4cd4e1b1d95dfb0f78896677ea1026af7510b41fabd3bd5771311c0cb6968337b2
# test data 3:
# xprv_str: 74a49c698dbd3c12e36b0b287447d833f74f3937ff132ebff7054baa18623c35a705bb18b82e2ac0384b5127db97016e63609f712bc90e3506cfbea97599f46f
# xpub_str: 522940d6440fdc45363df2097e9cac29a9a8a33ac339f8b7cff848c199db5a1ca705bb18b82e2ac0384b5127db97016e63609f712bc90e3506cfbea97599f46f
def xprv_to_xpub(xprv_str):
- private_key = ed25519.SigningKey(bytes.fromhex(xprv_str[:64]))
- public_key = private_key.get_verifying_key().to_ascii(encoding='hex')
- xpub_str = public_key.decode() + xprv_str[64:]
+ xprv_bytes = bytes.fromhex(xprv_str)
+ scalar = decodeint(xprv_bytes[:len(xprv_bytes)//2])
+ buf = encodepoint(scalarmultbase(scalar))
+ xpub = buf + xprv_bytes[len(xprv_bytes)//2:]
+ xpub_str = xpub.hex()
return xpub_str