Blind signature support in pyelliptic #1509
No reviewers
Labels
No Label
bug
build
dependencies
developers
documentation
duplicate
enhancement
formatting
invalid
legal
mobile
obsolete
packaging
performance
protocol
question
refactoring
regression
security
test
translation
usability
wontfix
No Milestone
No project
No Assignees
1 Participants
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Bitmessage/PyBitmessage-2024-12-09#1509
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "blindsig1"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
minimal implementation to pass a test
I'll fix the pylint complaints.
Honestly, I don't understand what exactly is going on here, but your test case may be better.
Shebang is not needed here.
from pybitmessage.pyelliptic.eccblind import ECCBlind
self.assertTrue(blind_sig.verify())
If you write docstring in one line it will be shown in the test results. e.g.
@g1itch I'll make the changes you requested.
The low level math I also don't understand, but it looks like it does what the paper says. On a high level, the paper mentions 5 steps (in Section 4), these are roughly mapped to 6 high level methods in the
ECCBlind
class, with some reshuffling because some are executed by the signer and some by the requester. It needs to be refactored, because the signer and requester need to communicate and pass data, so there will be one object at the signer's side and one at the requester's side, but here I just reuse a single object. Also in__init__
, it now generates a new pubkey, wereas for actual deployment the pubkey will be loaded from the disk (like a CA for traditional PKI). There still are open questions about how to serialise the data. This all will be solved in the subsequent PRs.This breaks the test.
It depends on how you run it.
Travis CI should be OK, because I used such imports before: https://github.com/Bitmessage/PyBitmessage/blob/v0.6/src/tests/test_config.py#L8
I also expected to find the blinded message and its signature and check the signature's validity.
@g1itch The message is only blinded internally and such blinded message is only available to the requester, it's not made public. Similarly with the blinded signature, that's calculated by the signer and then transmitted to the requester and unblinded by him.
What you see publicly is the message (in the case of PyBitmessage's wire protocol, this will be the object data), the signature (which has two components,
s
andF
), and pubkey of the signer (Q
). There is alsor
, but that's derived fromF
.F
is a point on a finite field andr
is its x coordinate modulo n, although it looks to me like the current code skips the modulo n, the way I understand the code is that n is selected from the elliptic curve used, so x can't higher than that. But I don't really understand ECC so I may be wrong.Then during the verification, you take the signature, the signer's pubkey and the message, and if verification succeeds, it means the singer signed the message, just like with traditional PKI, except here the signer doesn't know which of the requests he signed correspond to which message..
@ -0,0 +59,4 @@
"""
Generate an ECC keypair
"""
d = ECCBlind.ec_get_random(group, ctx)
d = self.ec_get_random(group, ctx) ?
@ -0,0 +59,4 @@
"""
Generate an ECC keypair
"""
d = ECCBlind.ec_get_random(group, ctx)
pylint/flake8 complained.
@ -0,0 +59,4 @@
"""
Generate an ECC keypair
"""
d = ECCBlind.ec_get_random(group, ctx)
because of
@staticmethod
. well, maybe this really should be a static methodI am trying to split signer and requester with no luck ):
let me try...
@g1itch here you go.
@ -0,0 +24,4 @@
requester_obj = ECCBlind(pubkey=signer_obj.pubkey)
# only 64 byte messages are planned to be used in Bitmessage
msg = os.urandom(64)
msg_blinded = requester_obj.create_signing_request(point_r, msg)
Maybe
self.assertNotEqual(msg, msg_blinded)
?@ -0,0 +24,4 @@
requester_obj = ECCBlind(pubkey=signer_obj.pubkey)
# only 64 byte messages are planned to be used in Bitmessage
msg = os.urandom(64)
msg_blinded = requester_obj.create_signing_request(point_r, msg)
Well that will always succeed as msg is a string and msg_blinded is an openssl bignum, but I can convert it before comparison, and I can also compare blinded an unblinded signature (those should both be bignums already).
As I said before, there is still no serialisation for the wire protocol, as that has to be designed first, then there will be minor refactoring here.
@ -0,0 +24,4 @@
requester_obj = ECCBlind(pubkey=signer_obj.pubkey)
# only 64 byte messages are planned to be used in Bitmessage
msg = os.urandom(64)
msg_blinded = requester_obj.create_signing_request(point_r, msg)
They will obviously differ. That's just a tests logic (as I understand it) to compare just in case and document it. Maybe that's unnecessary.
Serialization will be probably done in the
network
package, so it's not related to the blind signature implementation itself. The signatures seems to work well. So are you going to merge this now?@ -0,0 +24,4 @@
requester_obj = ECCBlind(pubkey=signer_obj.pubkey)
# only 64 byte messages are planned to be used in Bitmessage
msg = os.urandom(64)
msg_blinded = requester_obj.create_signing_request(point_r, msg)
I'll add the tests and then merge.
@g1itch I added tests to compare signature with blinded signature, and message with blinded message, all in form which serialises data to bytes with OpenSSL.BN_bn2bin and ctypes.cast. I think this format is usable on wire but more tests are needed.