From db92b13f9788f7224782a9635fc76ee3593e577c Mon Sep 17 00:00:00 2001 From: matejcik Date: Thu, 17 May 2018 12:53:01 +0200 Subject: [PATCH] cosi: move things around ed25519raw is moved back to trezorlib ed25519cosi is renamed to cosi, and has a couple more functions, with the expectation that TrezorClient.cosi_* methods will move there. Also most code shouldn't need ed25519raw for anything, so it might get renamed to "_ed25519" to indicate that it's a private implementation. For now, I added a "verify" method to cosi, so that you don't need to call into ed25519raw.checkvalid. But trezor-core's keyctl is also using ed25519raw.publickey. I'm not sure if that's worth replicating in cosi, or whether to just leave it be, so I'm leaving it be for now. Importantly, new function "sign_with_privkey" does that math thing that was part of the selftest and is also explicitly listed in keyctl. (it's called sign_with_privkey because I expect to have a "sign" method here that calls into Trezor) --- .../{tests/support/ed25519cosi.py => cosi.py} | 37 ++++++++++--------- trezorlib/{tests/support => }/ed25519raw.py | 0 trezorlib/tests/device_tests/test_cosi.py | 10 ++--- 3 files changed, 25 insertions(+), 22 deletions(-) rename trezorlib/{tests/support/ed25519cosi.py => cosi.py} (71%) rename trezorlib/{tests/support => }/ed25519raw.py (100%) diff --git a/trezorlib/tests/support/ed25519cosi.py b/trezorlib/cosi.py similarity index 71% rename from trezorlib/tests/support/ed25519cosi.py rename to trezorlib/cosi.py index 645dc29b5d..0c7a22c87d 100644 --- a/trezorlib/tests/support/ed25519cosi.py +++ b/trezorlib/cosi.py @@ -2,7 +2,7 @@ import sys from functools import reduce import binascii -from . import ed25519raw +from trezorlib import ed25519raw def combine_keys(pks): @@ -26,13 +26,24 @@ def get_nonce(sk, data, ctr): return r, ed25519raw.encodepoint(R) +def verify(signature, digest, pub_key): + ed25519raw.checkvalid(signature, digest, pub_key) + + +def sign_with_privkey(digest, privkey, global_pubkey, nonce, global_commit): + h = ed25519raw.H(privkey) + b = ed25519raw.b + a = 2 ** (b - 2) + sum(2 ** i * ed25519raw.bit(h, i) for i in range(3, b - 2)) + S = (nonce + ed25519raw.Hint(global_commit + global_pubkey + digest) * a) % ed25519raw.l + return ed25519raw.encodeint(S) + + def self_test(digest): def to_hex(by): return binascii.hexlify(by).decode() N = 3 - keyset = [0, 2] digest = binascii.unhexlify(digest) print('Digest: %s' % to_hex(digest)) @@ -56,29 +67,21 @@ def self_test(digest): nonces.append(r) commits.append(R) - global_pk = combine_keys([pks[i] for i in keyset]) - global_R = combine_keys([commits[i] for i in keyset]) + global_pk = combine_keys(pks) + global_R = combine_keys(commits) print('-----------------') print('Global pubkey: %s' % to_hex(global_pk)) print('Global commit: %s' % to_hex(global_R)) print('-----------------') - for i in range(0, N): - seckey = sks[i] - pubkey = pks[i] - r = nonces[i] - R = commits[i] - h = ed25519raw.H(seckey) - b = ed25519raw.b - a = 2**(b - 2) + sum(2 ** i * ed25519raw.bit(h, i) for i in range(3, b - 2)) - S = (r + ed25519raw.Hint(global_R + global_pk + digest) * a) % ed25519raw.l - print('Local sig %d: %s' % (i + 1, to_hex(ed25519raw.encodeint(S)))) - sigs.append(ed25519raw.encodeint(S)) + sigs = [sign_with_privkey(digest, sks[i], global_pk, nonces[i], global_R) for i in range(N)] + for sig in sigs: + print('Local signature: %s' % to_hex(sig)) print('-----------------') - sig = combine_sig(global_R, [sigs[i] for i in keyset]) + sig = combine_sig(global_R, sigs) print('Global sig: %s' % to_hex(sig)) - ed25519raw.checkvalid(sig, digest, global_pk) + verify(sig, digest, global_pk) print('Valid Signature!') diff --git a/trezorlib/tests/support/ed25519raw.py b/trezorlib/ed25519raw.py similarity index 100% rename from trezorlib/tests/support/ed25519raw.py rename to trezorlib/ed25519raw.py diff --git a/trezorlib/tests/device_tests/test_cosi.py b/trezorlib/tests/device_tests/test_cosi.py index 33e7ff9afa..45807915aa 100644 --- a/trezorlib/tests/device_tests/test_cosi.py +++ b/trezorlib/tests/device_tests/test_cosi.py @@ -20,7 +20,7 @@ import pytest from hashlib import sha256 from .common import TrezorTest -from ..support import ed25519cosi, ed25519raw +from trezorlib import cosi from trezorlib.tools import parse_path @@ -68,13 +68,13 @@ class TestCosi(TrezorTest): c1 = self.client.cosi_commit(parse_path("10018'/1'"), digest) c2 = self.client.cosi_commit(parse_path("10018'/2'"), digest) - global_pk = ed25519cosi.combine_keys([c0.pubkey, c1.pubkey, c2.pubkey]) - global_R = ed25519cosi.combine_keys([c0.commitment, c1.commitment, c2.commitment]) + global_pk = cosi.combine_keys([c0.pubkey, c1.pubkey, c2.pubkey]) + global_R = cosi.combine_keys([c0.commitment, c1.commitment, c2.commitment]) sig0 = self.client.cosi_sign(parse_path("10018'/0'"), digest, global_R, global_pk) sig1 = self.client.cosi_sign(parse_path("10018'/1'"), digest, global_R, global_pk) sig2 = self.client.cosi_sign(parse_path("10018'/2'"), digest, global_R, global_pk) - sig = ed25519cosi.combine_sig(global_R, [sig0.signature, sig1.signature, sig2.signature]) + sig = cosi.combine_sig(global_R, [sig0.signature, sig1.signature, sig2.signature]) - ed25519raw.checkvalid(sig, digest, global_pk) + cosi.verify(sig, digest, global_pk)