Skip to content

Commit

Permalink
Merge pull request #85 from LedgerHQ/develop
Browse files Browse the repository at this point in the history
Merge develop into master (B2CA-1710)
  • Loading branch information
tdejoigny-ledger authored Jul 17, 2024
2 parents 7077175 + 310a693 commit c10053c
Show file tree
Hide file tree
Showing 483 changed files with 1,305 additions and 613 deletions.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
- [ ] Target branch is `develop` <!-- unless you have a very good reason -->
- [ ] Application version has been bumped <!-- required if your changes are to be deployed -->

<!-- Make sure you followed the process described in https://developers.ledger.com/docs/embedded-app/maintenance/ before opening your Pull Request.
<!-- Make sure you followed the process described in https://developers.ledger.com/docs/device-app/deliver/maintenance before opening your Pull Request.
Don't hesitate to contact us directly on Discord if you have any questions ! https://developers.ledger.com/discord -->
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ examples/protocol

# Temporary test snapshots
tests/snapshots-tmp

# Virtual env for sideload (macOS and Windows)
ledger/

1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ ICON_NANOS = icons/nanos_app_tron.gif
ICON_NANOX = icons/nanox_app_tron.gif
ICON_NANOSP = icons/nanox_app_tron.gif
ICON_STAX = icons/stax_app_tron.gif
ICON_FLEX = icons/flex_app_tron.gif

ENABLE_BLUETOOTH = 1
ENABLE_SWAP = 1
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.5.0
0.7.0
51 changes: 40 additions & 11 deletions examples/base.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,43 @@
import struct


def parse_bip32_path(path):
if len(path) == 0:
return ""
result = ""
elements = path.split('/')
for pathElement in elements:
element = pathElement.split('\'')
if len(element) == 1:
result = result + struct.pack(">I", int(element[0])).hex()
else:
result = result + struct.pack(">I", 0x80000000 | int(element[0])).hex()
return result
if len(path) == 0:
return ""
result = ""
elements = path.split('/')
for pathElement in elements:
element = pathElement.split('\'')
if len(element) == 1:
result = result + struct.pack(">I", int(element[0])).hex()
else:
result = result + struct.pack(">I",
0x80000000 | int(element[0])).hex()
return result


def parse_bip32_path_to_bytes(path):
if len(path) == 0:
return b""
result = b""
elements = path.split('/')
for pathElement in elements:
element = pathElement.split('\'')
if len(element) == 1:
result = result + struct.pack(">I", int(element[0]))
else:
result = result + struct.pack(">I", 0x80000000 | int(element[0]))
return result


def apduMessage(INS, P1, P2, PATH, MESSAGE):
hexString = ""
if PATH:
hexString = "E0{:02x}{:02x}{:02x}{:02x}{:02x}{}".format(
INS, P1, P2, (len(PATH) + len(MESSAGE)) // 2 + 1,
len(PATH) // 4 // 2, PATH + MESSAGE)
else:
hexString = "E0{:02x}{:02x}{:02x}{:02x}{}".format(
INS, P1, P2,
len(MESSAGE) // 2, MESSAGE)
return bytearray.fromhex(hexString)
44 changes: 24 additions & 20 deletions examples/ecdh_eke.py.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,29 @@
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from secrets import token_bytes


class DiffieHellman:

def __init__(self):
self.diffieHellman = ec.derive_private_key(0xb5a4cea271ff424d7c31dc12a3e43e401df7a40d7412a15750f3f0b6b5449a28,ec.SECP256K1(), default_backend())
self.diffieHellman = ec.derive_private_key(
0xb5a4cea271ff424d7c31dc12a3e43e401df7a40d7412a15750f3f0b6b5449a28,
ec.SECP256K1(), default_backend())
self.public_key = self.diffieHellman.public_key()
self.IV = token_bytes(16)

def encrypt(self, public_key, secret):
shared_key = self.diffieHellman.exchange(ec.ECDH(), public_key)
print("Shared")
print(shared_key.hex())
derived_key = HKDF(
algorithm=hashes.SHA256(),
length=32,
salt=None,
info=None,
backend=default_backend()
).derive(shared_key)

aes = Cipher(algorithms.AES(derived_key), modes.CBC(self.IV), backend=default_backend())
derived_key = HKDF(algorithm=hashes.SHA256(),
length=32,
salt=None,
info=None,
backend=default_backend()).derive(shared_key)

aes = Cipher(algorithms.AES(derived_key),
modes.CBC(self.IV),
backend=default_backend())
encryptor = aes.encryptor()

padder = padding.PKCS7(128).padder()
Expand All @@ -34,15 +38,15 @@ def encrypt(self, public_key, secret):

def decrypt(self, public_key, secret, iv):
shared_key = self.diffieHellman.exchange(ec.ECDH(), public_key)
derived_key = HKDF(
algorithm=hashes.SHA256(),
length=32,
salt=None,
info=None,
backend=default_backend()
).derive(shared_key)

aes = Cipher(algorithms.AES(derived_key), modes.CBC(iv), backend=default_backend())
derived_key = HKDF(algorithm=hashes.SHA256(),
length=32,
salt=None,
info=None,
backend=default_backend()).derive(shared_key)

aes = Cipher(algorithms.AES(derived_key),
modes.CBC(iv),
backend=default_backend())
decryptor = aes.decryptor()
decrypted_data = decryptor.update(secret) + decryptor.finalize()

Expand All @@ -59,4 +63,4 @@ def decrypt(self, public_key, secret, iv):
print(encrypted_message)

decrypted_message = alice.decrypt(bob.public_key, encrypted_message, bob.IV)
print(decrypted_message)
print(decrypted_message)
29 changes: 16 additions & 13 deletions examples/getPublicKey.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
from base import parse_bip32_path

parser = argparse.ArgumentParser()
parser.add_argument('--path', help="BIP32 path to retrieve. e.g. \"44'/195'/0'/0/0\".")
parser.add_argument('--path',
help="BIP32 path to retrieve. e.g. \"44'/195'/0'/0/0\".")
args = parser.parse_args()

if args.path == None:
args.path = "44'/195'/0'/0/0"
args.path = "44'/195'/0'/0/0"

donglePath = parse_bip32_path(args.path)

Expand All @@ -21,24 +22,26 @@
# Ask for confirmation
# txt = "E0020100" + '{:02x}'.format(len(donglePath) + 1) + '{:02x}'.format( int(len(donglePath) / 4 / 2)) + donglePath
# No confirmation
apduMessage = "E0020000" + '{:02x}'.format(int(len(donglePath)/2) ) + '{:02x}'.format(int(len(donglePath) / 4 / 2)) + donglePath
apduMessage = "E0020000" + '{:02x}'.format(int(
len(donglePath) / 2)) + '{:02x}'.format(int(
len(donglePath) / 4 / 2)) + donglePath
apdu = bytearray.fromhex(apduMessage)

print("-= Tron Ledger =-")
print("Request Public Key")

dongle = getDongle(True)
result = dongle.exchange(apdu)
size=result[0]
if size == 65 :
print("Public Key: " + result[1:1+size].hex())
size = result[0]
if size == 65:
print("Public Key: " + result[1:1 + size].hex())
else:
print("Error... Public Key Size: {:d}".format(size))
print("Error... Public Key Size: {:d}".format(size))

size=result[size+1]
if size == 34 :
print("Address: " + result[67:67+size].decode())
if (result[67:67+size].decode()=="TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH"):
print("Address match with test case!")
size = result[size + 1]
if size == 34:
print("Address: " + result[67:67 + size].decode())
if (result[67:67 + size].decode() == "TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH"):
print("Address match with test case!")
else:
print("Error... Address Size: {:d}".format(size))
print("Error... Address Size: {:d}".format(size))
2 changes: 1 addition & 1 deletion examples/getVersion.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
dongle = getDongle(True)
result = dongle.exchange(bytearray.fromhex(apduMessage))

print('Version={:d}.{:d}.{:d}'.format(result[1],result[2],result[3]))
print('Version={:d}.{:d}.{:d}'.format(result[1], result[2], result[3]))
81 changes: 49 additions & 32 deletions examples/multisignTransfer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys

sys.path.append("./examples/proto")

from pprint import pprint
Expand All @@ -15,7 +16,8 @@
import binascii
import base58

logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
logging.basicConfig(level=logging.DEBUG,
format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger()

# Start Ledger
Expand All @@ -27,50 +29,67 @@ def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i + n]


def apduMessage(INS, P1, P2, PATH, MESSAGE):
hexString = ""
if PATH:
hexString = "E0{:02x}{:02x}{:02x}{:02x}{:02x}{}".format(INS,P1,P2,(len(PATH)+len(MESSAGE))//2+1,len(PATH)//4//2,PATH+MESSAGE)
hexString = "E0{:02x}{:02x}{:02x}{:02x}{:02x}{}".format(
INS, P1, P2, (len(PATH) + len(MESSAGE)) // 2 + 1,
len(PATH) // 4 // 2, PATH + MESSAGE)
else:
hexString = "E0{:02x}{:02x}{:02x}{:02x}{}".format(INS,P1,P2,len(MESSAGE)//2,MESSAGE)
hexString = "E0{:02x}{:02x}{:02x}{:02x}{}".format(
INS, P1, P2,
len(MESSAGE) // 2, MESSAGE)
print(hexString)
return bytearray.fromhex(hexString)


def ledgerSign(PATH, tx, tokenSignature=[]):
raw_tx = tx.raw_data.SerializeToString().hex()
# Sign in chunks
chunkList = list(chunks(raw_tx,420))
if len(tokenSignature)>0:
chunkList = list(chunks(raw_tx, 420))
if len(tokenSignature) > 0:
chunkList.extend(tokenSignature)

# P1 = P1_FIRST = 0x00
if len(chunkList)>1:
result = dongle.exchange(apduMessage(0x04,0x00,0x00, PATH, chunkList[0]))
if len(chunkList) > 1:
result = dongle.exchange(
apduMessage(0x04, 0x00, 0x00, PATH, chunkList[0]))
else:
result = dongle.exchange(apduMessage(0x04,0x10,0x00, PATH, chunkList[0]))
result = dongle.exchange(
apduMessage(0x04, 0x10, 0x00, PATH, chunkList[0]))

for i in range(1,len(chunkList)-1-len(tokenSignature)):
for i in range(1, len(chunkList) - 1 - len(tokenSignature)):
# P1 = P1_MODE = 0x80
result = dongle.exchange(apduMessage(0x04,0x80,0x00, None, chunkList[i]))

for i in range(0,len(tokenSignature)-1):
result = dongle.exchange(apduMessage(0x04,0xA0 | (0x00+i), 0x00, None, tokenSignature[i]))

result = dongle.exchange(
apduMessage(0x04, 0x80, 0x00, None, chunkList[i]))

for i in range(0, len(tokenSignature) - 1):
result = dongle.exchange(
apduMessage(0x04, 0xA0 | (0x00 + i), 0x00, None,
tokenSignature[i]))

# P1 = P1_LAST = 0x90
if len(chunkList)>1:
if len(tokenSignature)>0:
result = dongle.exchange(apduMessage(0x04,0xA0 | 0x08 | (0x00+len(tokenSignature)-1),0x00, None, chunkList[len(chunkList)-1]))
if len(chunkList) > 1:
if len(tokenSignature) > 0:
result = dongle.exchange(
apduMessage(0x04,
0xA0 | 0x08 | (0x00 + len(tokenSignature) - 1),
0x00, None, chunkList[len(chunkList) - 1]))
else:
result = dongle.exchange(apduMessage(0x04,0x90,0x00, None, chunkList[len(chunkList)-1]))
result = dongle.exchange(
apduMessage(0x04, 0x90, 0x00, None,
chunkList[len(chunkList) - 1]))

return raw_tx, result


def address_hex(address):
return base58.b58decode_check(address).hex().upper()


# Get Addresses
logger.debug('-= Tron Ledger =-')

'''
Tron Protobuf
'''
Expand All @@ -90,26 +109,24 @@ def address_hex(address):
''')

tx = stub.CreateTransaction2(
contract.TransferContract(
owner_address=bytes.fromhex(address_hex("TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH")),
to_address=bytes.fromhex(address_hex("TPnYqC2ukKyhEDAjqRRobSVygMAb8nAcXM")),
amount=100000
)
)
contract.TransferContract(
owner_address=bytes.fromhex(
address_hex("TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH")),
to_address=bytes.fromhex(
address_hex("TPnYqC2ukKyhEDAjqRRobSVygMAb8nAcXM")),
amount=100000))
# use permission 2
tx.transaction.raw_data.contract[0].Permission_id=2


tx.transaction.raw_data.contract[0].Permission_id = 2

raw_tx, sign1 = ledgerSign(parse_bip32_path("44'/195'/0'/0/0"),tx.transaction)
raw_tx, sign2 = ledgerSign(parse_bip32_path("44'/195'/1'/0/0"),tx.transaction)
raw_tx, sign1 = ledgerSign(parse_bip32_path("44'/195'/0'/0/0"), tx.transaction)
raw_tx, sign2 = ledgerSign(parse_bip32_path("44'/195'/1'/0/0"), tx.transaction)

tx.transaction.signature.extend([bytes(sign1[0:65])])
tx.transaction.signature.extend([bytes(sign2[0:65])])

r = stub.BroadcastTransaction(tx.transaction)

if r.result == True:
print("Success")
print("Success")
else:
print("Fail")
print("Fail")
Loading

0 comments on commit c10053c

Please sign in to comment.