Add SecretPoint. Improve SecretScalar#92
Conversation
maurges
commented
Jun 17, 2026
- SecretPoint is like SecretScalar but for points
- Add Zeroize instance to scalar and point byte representations
- SecretPoint and SecretScalar provide methods to get secret bytes
Signed-off-by: maurges <git@morj.men>
Signed-off-by: maurges <git@morj.men>
Signed-off-by: maurges <git@morj.men>
Signed-off-by: maurges <git@morj.men>
Signed-off-by: maurges <git@morj.men>
For some reason cargo build --no-default-features didn't fully check every definition? Signed-off-by: maurges <git@morj.men>
Signed-off-by: maurges <git@morj.men>
| pub(super) fn inner<T>(x: Secret<T>) -> T | ||
| where | ||
| T: zeroize::Zeroize + Clone, | ||
| { | ||
| (**x).clone() |
There was a problem hiding this comment.
The function signature suggest that it takes ownership of x and retrieves the wrapped value, where as in reality it just clones the wrapped value.
- I think it should accept
x: &Secret<T>. It's not only clearer, but also more efficient, as we don't need to increment/decrementArc's reference counter - Another name could be a better fit. E.g.
clone_inner?
There was a problem hiding this comment.
When I was implementing this, I was thinking about the non-Arc case: you take the secret value, take it out of the Zeroizing, and obtain a non-secret. But then I realized that you can't into_inner the Zeroizing struct, and can only clone from within, but I was commited to the function idea. Now I need to reflect on what I want from it.
| } | ||
|
|
||
| /// Convert the representation into not-secret, dropping all guarantees | ||
| pub fn into_not_secret(self) -> EncodedPoint<E> { |
There was a problem hiding this comment.
I like the naming. Probably, SecretScalar::as_ref() should be renamed into as_not_secret() to be clearer.
That would break the API, but we could deprecate as_ref and provide a new as_not_secret as the suggested replacement.
There was a problem hiding this comment.
Ah I just realized that we can't do that, since we rely a lot on that &SecretScalar can be passed to a function that accepts x: impl AsRef<Scalar<E>>...
There was a problem hiding this comment.
I can add the method with this name at least
There was a problem hiding this comment.
Though its implementation will be as stupid as for the encoded one, with clone, because as I see I can't convert out of Zeroizing.
Unless we want to use unsafe transmute, which will work because Zeroizing is guaranteed to have the same representation
There was a problem hiding this comment.
Though its implementation will be as stupid as for the encoded one, with clone, because as I see I can't convert out of Zeroizing.
Why? You can reference inner data (via Deref on Zeroizing), you don't need to clone it
There was a problem hiding this comment.
I think this method would be a great addition. It would replicate existing AsRef implementation. We might consider in the future removing AsRef to force users using explicit method with "dangerous" name.
|
|
||
| /// Obtain the reference to the encoded bytes. This bypasses all the secrecy | ||
| /// guarantees, so be careful when handling them | ||
| pub fn as_bytes(&self) -> &[u8] { |
There was a problem hiding this comment.
in the spirit of into_not_secret method, I'm inclined to propose to rename this one to as_not_secret_bytes, though that becomes quite long (but maybe it's justified?)
There was a problem hiding this comment.
Maybe slight shortening to as_nonsecret_bytes? I was initially debating the method name between into_not_secret and into_nonsecret
There was a problem hiding this comment.
as_nonsecret_bytes sounds good to me!
Signed-off-by: maurges <git@morj.men>
Signed-off-by: maurges <git@morj.men>
| @@ -0,0 +1,55 @@ | |||
| //! Internals for both Secret structs, like `SecretScalar` and `SecretEncodedPoint`. They have a different representation based on the presence of `alloc`: either a reference-counted nonmoving one, or a moving value | |||
There was a problem hiding this comment.
(there are more than 2 secret structs)
| //! Internals for both Secret structs, like `SecretScalar` and `SecretEncodedPoint`. They have a different representation based on the presence of `alloc`: either a reference-counted nonmoving one, or a moving value | |
| //! Internals for Secret structs, like `SecretScalar` and `SecretEncodedPoint`. They have a different representation based on the presence of `alloc`: either a reference-counted nonmoving one, or a moving value |
| } | ||
|
|
||
| /// Convert the representation into not-secret, dropping all guarantees | ||
| pub fn into_not_secret(self) -> EncodedPoint<E> { |
There was a problem hiding this comment.
Though its implementation will be as stupid as for the encoded one, with clone, because as I see I can't convert out of Zeroizing.
Why? You can reference inner data (via Deref on Zeroizing), you don't need to clone it
| value_on_heap | ||
| } | ||
|
|
||
| pub fn inner<T>(x: Secret<T>) -> T |
There was a problem hiding this comment.
clone_inner feels like better name for it