1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-13 19:18:56 +00:00

add test_debuglink test

This commit is contained in:
Pavol Rusnak 2014-02-06 23:34:13 +01:00
parent eeb6a847ea
commit 49cecb563d
4 changed files with 50 additions and 105 deletions

25
tests/test_debuglink.py Normal file
View File

@ -0,0 +1,25 @@
import time
import unittest
import common
import binascii
from trezorlib import messages_pb2 as proto
from trezorlib import types_pb2 as types
from trezorlib.client import PinException
class TestDebugLink(common.TrezorTest):
def test_layout(self):
layout = self.client.debuglink.read_layout()
print binascii.hexlify(layout)
def test_mnemonic(self):
mnemonic = self.client.debuglink.read_mnemonic()
print mnemonic
def test_node(self):
node = self.client.debuglink.read_node()
print node
if __name__ == '__main__':
unittest.main()

View File

@ -7,7 +7,6 @@ from ecdsa.util import string_to_number, number_to_string
from ecdsa.curves import SECP256k1
from ecdsa.ellipticcurve import Point, INFINITY
import msqrt
import tools
import types_pb2 as proto_types
@ -31,7 +30,7 @@ def sec_to_public_pair(pubkey):
curve = generator.curve()
p = curve.p()
alpha = (pow(x, 3, p) + curve.a() * x + curve.b()) % p
beta = msqrt.modular_sqrt(alpha, p)
beta = ecdsa.number_theory.square_root_mod_prime(alpha, p)
if is_even == bool(beta & 1):
return (x, p - beta)
return (x, beta)

View File

@ -6,36 +6,51 @@ def pin_info(pin):
def button_press(yes_no):
print "User pressed", '"y"' if yes_no else '"n"'
class DebugLink(object):
def __init__(self, transport, pin_func=pin_info, button_func=button_press):
self.transport = transport
self.pin_func = pin_func
self.button_func = button_func
def read_pin(self):
self.transport.write(proto.DebugLinkGetState())
obj = self.transport.read_blocking()
print "Read PIN:", obj.pin
print "Read matrix:", obj.matrix
return (obj.pin, obj.matrix)
def read_pin_encoded(self):
pin, matrix = self.read_pin()
# Now we have real PIN and PIN matrix.
# We have to encode that into encoded pin,
# because application must send back positions
# on keypad, not a real PIN.
pin_encoded = ''.join([ str(matrix.index(p) + 1) for p in pin])
print "Encoded PIN:", pin_encoded
self.pin_func(pin_encoded)
return pin_encoded
def read_layout(self):
self.transport.write(proto.DebugLinkGetState())
obj = self.transport.read_blocking()
return obj.layout
def read_mnemonic(self):
self.transport.write(proto.DebugLinkGetState())
obj = self.transport.read_blocking()
return obj.mnemonic
def read_node(self):
self.transport.write(proto.DebugLinkGetState())
obj = self.transport.read_blocking()
return obj.node
def press_button(self, yes_no):
print "Pressing", yes_no
self.button_func(yes_no)
@ -43,7 +58,7 @@ class DebugLink(object):
def press_yes(self):
self.press_button(True)
def press_no(self):
self.press_button(False)

View File

@ -1,94 +0,0 @@
# from http://eli.thegreenplace.net/2009/03/07/computing-modular-square-roots-in-python/
def modular_sqrt(a, p):
""" Find a quadratic residue (mod p) of 'a'. p
must be an odd prime.
Solve the congruence of the form:
x^2 = a (mod p)
And returns x. Note that p - x is also a root.
0 is returned is no square root exists for
these a and p.
The Tonelli-Shanks algorithm is used (except
for some simple cases in which the solution
is known from an identity). This algorithm
runs in polynomial time (unless the
generalized Riemann hypothesis is false).
"""
# Simple cases
#
if legendre_symbol(a, p) != 1:
return 0
elif a == 0:
return 0
elif p == 2:
return p
elif p % 4 == 3:
return pow(a, (p + 1) / 4, p)
# Partition p-1 to s * 2^e for an odd s (i.e.
# reduce all the powers of 2 from p-1)
#
s = p - 1
e = 0
while s % 2 == 0:
s /= 2
e += 1
# Find some 'n' with a legendre symbol n|p = -1.
# Shouldn't take long.
#
n = 2
while legendre_symbol(n, p) != -1:
n += 1
# Here be dragons!
# Read the paper "Square roots from 1; 24, 51,
# 10 to Dan Shanks" by Ezra Brown for more
# information
#
# x is a guess of the square root that gets better
# with each iteration.
# b is the "fudge factor" - by how much we're off
# with the guess. The invariant x^2 = ab (mod p)
# is maintained throughout the loop.
# g is used for successive powers of n to update
# both a and b
# r is the exponent - decreases with each update
#
x = pow(a, (s + 1) / 2, p)
b = pow(a, s, p)
g = pow(n, s, p)
r = e
while True:
t = b
m = 0
for m in xrange(r):
if t == 1:
break
t = pow(t, 2, p)
if m == 0:
return x
gs = pow(g, 2 ** (r - m - 1), p)
g = (gs * gs) % p
x = (x * gs) % p
b = (b * g) % p
r = m
def legendre_symbol(a, p):
""" Compute the Legendre symbol a|p using
Euler's criterion. p is a prime, a is
relatively prime to p (if p divides
a, then a|p = 0)
Returns 1 if a has a square root modulo
p, -1 otherwise.
"""
ls = pow(a, (p - 1) / 2, p)
return -1 if ls == p - 1 else ls