-
Notifications
You must be signed in to change notification settings - Fork 168
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
extras: Add EC toolbox abstractions and OPRF(P-384, SHA-384) VOPRF API #292
Conversation
c1c4ba9
to
0807220
Compare
9e94b78
to
fda1a2c
Compare
@Lukasa PTAL when you have time 🙏 |
@@ -72,6 +72,14 @@ extension BoringSSLEllipticCurveGroup { | |||
return try! ArbitraryPrecisionInteger(copying: baseOrder) | |||
} | |||
|
|||
@usableFromInline | |||
package var generator: EllipticCurvePoint { get throws { |
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.
Might be worth not squishing this in, get throws {
can be on its own line.
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.
OK, I moved this onto its own line.
Aside: I have a task to add the swift-format job to this repo soon, which will squash all these inconsistencies away.
try group.withUnsafeGroupPointer { groupPtr in | ||
guard | ||
let pointPtr = CCryptoBoringSSL_EC_POINT_new(groupPtr), | ||
CCryptoBoringSSL_EC_POINT_mul(groupPtr, pointPtr, scalarPtr, nil, nil, nil) == 1 |
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.
Not a new issue, but this leaks the pointPtr
if the mul fails.
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've addressed this by factoring out the EC_POINT_new
into a designated init(_pointAtInfinityOn group:)
and made all these convenience
initialisers.
try domainSeparationTag.withUnsafeBytes { dstPtr in | ||
guard | ||
let pointPtr = CCryptoBoringSSL_EC_POINT_new(groupPtr), | ||
hashToCurveFunction( |
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 this fails, we leak the point.
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.
Resolved in the same manner as https://github.com/apple/swift-crypto/pull/292/files/fda1a2c6df294e87b24b77ad28a7cd5950d74d25#r1850181741.
switch CCryptoBoringSSL_EC_POINT_cmp(groupPtr, selfPtr, rhsPtr, nil) { | ||
case 0: return true | ||
case 1: return false | ||
default: fatalError("Unexpected error testing EC point equality") |
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 don't know that we need to be this strict. 0
is true, everything else is false
. Happy to have an assertion for the other codes, but probably shouldn't fatal error.
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 think that's not quite right since the docs say that EC_POINT_cmp
can return an error:
EC_POINT_cmp returns 1 if the points are not equal, 0 if they are, or -1 on error.
I think this can happen if you provide a point on a different group for an equality test, for instance.
This function isn't throwing so the best we can do is fatal error, which seems to be in line with what we do elsewhere?
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'm not sure we need the error to be this loud, though. Perhaps we drop this to an assertion and then return false
?
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.
After further consideration, given we allow folks to pass in the group
, we shouldn't even assert, but just return false
if comparing two points from different groups.
I've updated the code to clear the BoringSSL error and return false
in this scenario.
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.
Thanks for the feedback @Lukasa. I've addressed your comments. Could you take another look when you get a minute.
switch CCryptoBoringSSL_EC_POINT_cmp(groupPtr, selfPtr, rhsPtr, nil) { | ||
case 0: return true | ||
case 1: return false | ||
default: fatalError("Unexpected error testing EC point equality") |
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 think that's not quite right since the docs say that EC_POINT_cmp
can return an error:
EC_POINT_cmp returns 1 if the points are not equal, 0 if they are, or -1 on error.
I think this can happen if you provide a point on a different group for an equality test, for instance.
This function isn't throwing so the best we can do is fatal error, which seems to be in line with what we do elsewhere?
@@ -72,6 +72,14 @@ extension BoringSSLEllipticCurveGroup { | |||
return try! ArbitraryPrecisionInteger(copying: baseOrder) | |||
} | |||
|
|||
@usableFromInline | |||
package var generator: EllipticCurvePoint { get throws { |
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.
OK, I moved this onto its own line.
Aside: I have a task to add the swift-format job to this repo soon, which will squash all these inconsistencies away.
try group.withUnsafeGroupPointer { groupPtr in | ||
guard | ||
let pointPtr = CCryptoBoringSSL_EC_POINT_new(groupPtr), | ||
CCryptoBoringSSL_EC_POINT_mul(groupPtr, pointPtr, scalarPtr, nil, nil, nil) == 1 |
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've addressed this by factoring out the EC_POINT_new
into a designated init(_pointAtInfinityOn group:)
and made all these convenience
initialisers.
try domainSeparationTag.withUnsafeBytes { dstPtr in | ||
guard | ||
let pointPtr = CCryptoBoringSSL_EC_POINT_new(groupPtr), | ||
hashToCurveFunction( |
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.
Resolved in the same manner as https://github.com/apple/swift-crypto/pull/292/files/fda1a2c6df294e87b24b77ad28a7cd5950d74d25#r1850181741.
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.
Nice one, thanks @simonjbeaumont!
Thanks @Lukasa :) please merge when convenient. |
Motivation
We would like to provide support for the P384-SHA384 Verifiable Oblivious Pseudorandom Function (VOPRF) as defined in RFC 9497: VOPRF Protocol.
Modifications
Group
,GroupElement
,GroupScalar
,HashToGroup
.enum P384._VOPRF
.Results
OPRF(P-384, SHA-384)
in VOPRF mode.Tests
HashToField
implementation.