-
Notifications
You must be signed in to change notification settings - Fork 17
feat(Signature): refactor and expand public-key signature API #170
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
feat(Signature): refactor and expand public-key signature API #170
Conversation
4161b82 to
38a88a3
Compare
38a88a3 to
55c20db
Compare
| -- | Signal your intent to encode secret key material for transmission | ||
| -- by wrapping a t'SecretKey' in t'UnsafeSecretKey'. | ||
| -- | ||
| -- @since 0.0.3.0 | ||
| newtype UnsafeSecretKey = UnsafeSecretKey SecretKey | ||
| deriving newtype | ||
| ( Eq | ||
| -- ^ @since 0.0.3.0 | ||
| -- Follows the t'SecretKey' instance. | ||
| ) | ||
| deriving | ||
| ( Display | ||
| -- ^ @since 0.0.3.0 | ||
| -- Hexadecimal-encoded bytes. | ||
| ) | ||
| via (ShowInstance UnsafeSecretKey) | ||
|
|
||
| -- | Hexadecimal-encoded bytes. | ||
| -- | ||
| -- @since 0.0.3.0 | ||
| instance Show UnsafeSecretKey where | ||
| show = ByteString.unpackChars . encodeSecretKeyHexByteString | ||
|
|
||
| -- | By lexicographical comparison of pointer contents. | ||
| -- | ||
| -- ⚠️ Vulnerable to timing attacks! | ||
| -- | ||
| -- @since 0.0.3.0 | ||
| instance Ord UnsafeSecretKey where | ||
| a `compare` b = | ||
| foreignPtrOrd (coerce a) (coerce b) cryptoSignSecretKeyBytes |
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 feels a bit over-engineered. encodeSecretKeyHexByteString ought to be a much simpler interface, no? I don't understand if there are invariants that are preserved by this type and its instances.
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.
It's intended as a guardrail to prevent you from doing things like serializing secret keys and using Ord in a way that's vulnerable to timing attacks without some kind of signal to readers that you're doing something that demands some extra attention.
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.
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 tend to prefer sticking such things behind a gate that's very slightly higher than that since unsafe is a very overloaded word. To my mind, it implies there's some safeSecretKeyToHexByteString waiting to be discovered, and there just isn't. Disjoint concepts <=> disjoint types. I'm not married to it, though, and with constant-time Ord coming quite soon I could be convinced the power-to-weight isn't 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.
That option is available in the present API as unsafeSecretKeyHexByteString, which just wraps whatever SecretKey in the newtype first.
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.
Pushed commits to strip that all out. Will update the API golden test once #171 lands and I rebase this PR on top of it.
6fb7ca6 to
b19f0de
Compare
f46f827 to
765c0de
Compare
Highlights: - Models input validation errors (pointer length and hex encoding) - Serde and rendering functions for `PublicKey`, `SecretKey`, and `SignedMessage` - Internals under `Scoped` - Uses constant-time `Eq` for `SecretKey`
For consistency, use `Foreign.copyBytes` everywhere that `memcpy` was once used.
765c0de to
0501798
Compare
0501798 to
53c2a55
Compare

Highlights:
Models input validation errors (pointer length and hex encoding)
Serde and rendering functions for
PublicKey,SecretKey, andSignedMessageInternals under
ScopedUses constant-time
EqandOrdforSecretKeyFor consistency, use
Foreign.copyByteseverywhere thatmemcpywas once used