funga

Signer and keystore daemon and library for cryptocurrency software development
Log | Files | Refs | README | LICENSE

commit 89144945bba731dbdfc85554c211a4141b72266d
parent 88c01e7edfae7bf4e2d4687ca521ab3778ba0528
Author: lash <dev@holbrook.no>
Date:   Fri, 23 Jun 2023 21:31:22 +0100

Verify sig from xml curve params

Diffstat:
Mfunga/xml/xml.py | 27+++++++++++++++++++++++----
Mtest_requirements.txt | 1+
Mtests/test_xml.py | 35++++++++++++++++++++++++++++++++++-
Mtests/testdata/sign.xml | 4++--
4 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/funga/xml/xml.py b/funga/xml/xml.py @@ -20,6 +20,15 @@ def cryptobinary_to_int(v): return int.from_bytes(b, byteorder='big') +def cryptobinary_to_pair(v): + b = b64decode(v) + b = b[1:] # TODO: force uncompressed + l = int(len(b) / 2) + x = int.from_bytes(b[:l], byteorder='big') + y = int.from_bytes(b[l:], byteorder='big') + return (x, y,) + + class SignatureParser: namespaces = { @@ -62,18 +71,24 @@ class SignatureParser: def clear(self): - self.signature = None + self.sig_r = None + self.sig_s = None + self.sig_v = None self.digest = None self.public_key = None self.prime = None self.curve_a = None self.curve_b = None - self.base = None + self.base_x = None + self.base_y = None self.order = None self.cofactor = None self.keyname = None + def __str__(self): + return 'order {}'.format(self.order) + def set(self, k, v): if k.__class__.__name__ == 'SignatureAccept': self.__settings[k.value - 1].append(v) @@ -124,7 +139,11 @@ class SignatureParser: m = self.get(SignatureVerify.SIGNATURE) if m != None: assert m(b) - self.signature = b + #self.signature = b + logg.debug('sig {}'.format(b.hex())) + self.sig_r = int.from_bytes(b[:32], byteorder='little') + self.sig_s = int.from_bytes(b[32:64], byteorder='little') + self.sig_v = int(b[64]) def __opt_verify_signedinfo(self, el): r = el.find('./DigestMethod', namespaces=self.namespaces) @@ -164,7 +183,7 @@ class SignatureParser: r = el.find('./dsig11:ECParameters/dsig11:Curve/dsig11:B', namespaces=self.namespaces) self.curve_b = cryptobinary_to_int(r.text) r = el.find('./dsig11:ECParameters/dsig11:Base', namespaces=self.namespaces) - self.base = cryptobinary_to_int(r.text) + (self.base_x, self.base_y) = cryptobinary_to_pair(r.text) r = el.find('./dsig11:ECParameters/dsig11:Order', namespaces=self.namespaces) self.order = cryptobinary_to_int(r.text) r = el.find('./dsig11:ECParameters/dsig11:CoFactor', namespaces=self.namespaces) diff --git a/test_requirements.txt b/test_requirements.txt @@ -0,0 +1 @@ +fastecdsa~=2.3.0 diff --git a/tests/test_xml.py b/tests/test_xml.py @@ -4,6 +4,10 @@ import unittest import os from base64 import b64decode +# external imports +from fastecdsa import curve +from fastecdsa import ecdsa + # local imports from funga.xml import SignatureParser from funga.xml import SignatureAccept @@ -73,10 +77,39 @@ class TestXmlSig(unittest.TestCase): self.parser.set(SignatureVerify.PUBLICKEY, verify_pub_ok) self.parser.process_file(self.xml_file) - self.assertEqual(self.parser.signature.hex(), 'af77767edbccdf46380fed6f06af43c807de4bedce2eda129923340e9577c97e76bc55d587103a367057167f351ae1cfd6b8dea6e0282257de3594fbe3d8780700') + #self.assertEqual(self.parser.signature.hex(), 'af77767edbccdf46380fed6f06af43c807de4bedce2eda129923340e9577c97e76bc55d587103a367057167f351ae1cfd6b8dea6e0282257de3594fbe3d8780700') self.assertEqual(self.parser.public_key.hex(), '049f6bb6a7e3f5b7ee71756a891233d1415658f8712bac740282e083dc9240f5368bdb3b256a5bf40a8f7f9753414cb447ee3f796c5f30f7eb40a7f5018fc7f02e') self.assertEqual(self.parser.digest.hex(), '76b2e96714d3b5e6eb1d1c509265430b907b44f72b2a22b06fcd4d96372b8565') + logg.debug('r {}'.format(self.parser)) + + c = curve.Curve( + 'eth', + self.parser.prime, + self.parser.curve_a, + self.parser.curve_b, + self.parser.order, + self.parser.base_x, + self.parser.base_y, + ) + + class Pubk: + def __init__(self, x, y): + self.x = x + self.y = y + + x = int.from_bytes(self.parser.public_key[1:33], byteorder='big') + y = int.from_bytes(self.parser.public_key[33:65], byteorder='big') + pubk = Pubk(x, y) + + ecdsa.verify( + (self.parser.sig_r, self.parser.sig_s), + self.parser.digest, + pubk, + curve=c, + ) + + if __name__ == '__main__': unittest.main() diff --git a/tests/testdata/sign.xml b/tests/testdata/sign.xml @@ -26,8 +26,8 @@ </Prime> </FieldID> <Curve> - <A>AAo=</A> - <B>Bwo=</B> + <A>AA==</A> + <B>Bw==</B> </Curve> <Base>BHm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ1Lg=</Base> <Order>/////////////////////rqu3OavSKA7v9JejNA2QUE=</Order>