-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SECP256k1 support #252
SECP256k1 support #252
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also add this new DSIGN algorithm to the test suite? It may not be obvious, but if you look in the cardano-crypto-tests
subproject, there's a file src/Test/Crypto/DSIGN.hs
, and adding the new algorithm is as simple as adding a line to the tests
data structure. You can pretty much just copy one of the existing lines and change the algorithm name to SECP256k1.
@tdammers I actually can't add the tests, due to this error:
This is caused by the fact that |
It does seem odd to have the Presumably @kozross there's a way to make a |
@michaelpj Yes, you can make a The primary issue here isn't what the
I'm happy to fix either issue, but I'd rather know which would be acceptable. |
I agree with your analysis, and personally I think it would be preferable for the tests to not assume that |
@michaelpj I've already worked out a fix to the tests which makes this assumption unnecessary. I still have some minor fixes to make so that all the SECP256k1 tests pass, but once that's done, it should be ready. At the same time, I've noticed some concerning issues with the tests themselves:
I suspect there may be more issues: these are just the ones I've spotted in the DSIGN tests. |
fc33421
to
22e79aa
Compare
I noticed you made some changes to the sizes, was that because they were wrong? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, so long as @tdammers is happy with the test changes.
Yes: the tests also caught me, so it's good that @tdammers told me about them. |
Conflicts with the other PR. |
@michaelpj I've addressed the conflicts - is this OK to merge? |
Tobias said he wanted to have a look at this today, so I'm waiting for that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't going to break anything, but I'm not 100% convinced that this is the best possible design here.
import Test.Tasty (TestTree, testGroup) | ||
import Test.Tasty.QuickCheck (testProperty) | ||
|
||
-- Captures ways of generating each of the associated types of DSIGN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it necessary to also provide a generalization of genVK and genSK, when we never use it? Can we not simply pass a Gen (SigDSIGN v)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, and this design also prevents shrinking, doesn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do use them. Consider line ranges 167-173, 180-187, 195-201, 208-209, 213-214, 218-223 at least. We also have several derived generators using one or both.
As far as preventing shrinking goes - we can't shrink anyway for almost anything, and indeed, the original design also prevented shrinking, since all shrinkers were defined as const []
. My changes have not removed any functionality or capability that existed before, but added plenty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, sorry about the confusion - yes, we are using the (quasi-)methods, but we are not using the ability to generalize - all the methodologies we define here use the same implementations for genVerKey
and genSignKey
, so we might as well just use default{Ver,Sign}KeyGen
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we did what I suggest below then we would need genSignKey
, but perhaps still not genVerKey
. Not sure it costs us much, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tdammers I'm happy to specialize in the way you describe. I don't think it's a particularly bad idea to have the ability to generalize in the way the verification and sign keys are generated, even if we don't use it currently, but I'm not strongly wedded to this.
Edit: This is now done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally understand the thinking here, it just tickles my YAGNI nerve. I would personally start with only generalizing what needs to be generalized, which, at this point, is only genSig
bit.
And, upon further thought, what we're really generalizing here isn't even generating a signature, but generating a message to sign. If you compare the defSigGen
function with the go
function inside the secp256k1Methodology
, the only difference is how the message is generated.
So what I would propose is that we ditch the TypesMethodology
type entirely, and instead just pass a generator for the message type (genSECPMsg
for secp256k1, arbitrary
for everything else), and then implement genSig
in terms of that.
-- Captures ways of generating each of the associated types of DSIGN | ||
data TypesMethodology (a :: Type) = | ||
TypesMethodology (Gen (VerKeyDSIGN a)) | ||
(Gen (SignKeyDSIGN a)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're going to do this, arguably we could get rid of the key generation method from the DSIGN
class, since it's presumably only used for testing, and this lets us give the generators per-type as we need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is potentially quite a breaking change, so I'm reluctant to do this unless absolutely necessary. I've fixed Tobias' original over-generality concern without this, but if you feel a change to DSIGN
is needed to get this merged, I can do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, not necessary, it just seems ugly to me to have the generator in there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remaining complaints from my side are largely cosmetic; as far as I'm concerned, we can merge now, and maybe bikeshed later.
👍 |
Naming in this PR is again incorrect. We should not use |
@iquerejeta What do you suggest instead? |
I would suggest using the signature algorithm's name. I'm not sure which one you have implemented here, but if it is ECDSA, I would go with something like |
@iquerejeta Thank you - that's a good solution. @michaelpj - can I combine the name-change with the Schnorr signature PR I'm working on, or do you want that done separately? |
Happy for them both to go together. |
This is the first stage of solving this issue, as per this request.
A few questions remain outstanding:
The size of the verification key (that is, public key) is not an exact multiple of 8 bits, as it's compressed and DER-encoded, for a total of 257 bits. I've thus set it to be 33 bytes in the implementation, but I am unsure if this is correct.Maybe
. According to the implementation, we ensure that the only invariant is met, but this seems suspicious.Tagging @michaelpj for review.