1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-26 17:38:39 +00:00

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)
This commit is contained in:
matejcik 2018-05-17 12:53:01 +02:00
parent f9c20f8d2f
commit db92b13f97
3 changed files with 25 additions and 22 deletions

View File

@ -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!')

View File

@ -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)