-
Notifications
You must be signed in to change notification settings - Fork 221
Add ed448 #1121
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
base: master
Are you sure you want to change the base?
Add ed448 #1121
Conversation
// The original file was a part of curve25519-dalek. | ||
// Copyright (c) 2016-2019 Isis Lovecruft, Henry de Valence | ||
// Copyright (c) 2020 Kevaundray Wedderburn | ||
// See LICENSE for licensing information. |
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.
lets add a reference to the actual licnes file from curve25519-dalek
@tarcieri @mikelodder7 I am not seeing much in terms of test vectors or the likes, do you happen to know where to find some? |
working on a pr to update to the current set of rustcrypto deps |
Co authors |
Here's the Ed448 test vectors |
created mikelodder7#1 |
👀 |
what's the status on this? It would be great to see ed448 under the RustCrypto umbrella. |
@dkg waiting on @mikelodder7 to rebase and get the tests passing |
Signed-off-by: Michael Lodder <[email protected]>
Signed-off-by: Michael Lodder <[email protected]>
Signed-off-by: Michael Lodder <[email protected]>
Signed-off-by: Michael Lodder <[email protected]>
Signed-off-by: Michael Lodder <[email protected]>
Signed-off-by: Michael Lodder <[email protected]>
Signed-off-by: Michael Lodder <[email protected]>
There's a little stuff about my previous contribution that I feel the need to renegotiate before the code gets into a serious place like RustCrypto. |
Signed-off-by: Michael Lodder <[email protected]>
Signed-off-by: Michael Lodder <[email protected]>
homepage = "https://docs.rs/ed448-goldilocks/" | ||
keywords = ["cryptography", "decaf", "ed448", "ed448-goldilocks"] | ||
license = "BSD-3-Clause" | ||
name = "ed448" |
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 keep the name as ed448-goldilocks
, it will allow the ed448
name to be used for the signature abstraction crate, which would be consistent with the ed25519
crate
(and that also ensures existing users get updates automatically without having to change to a new name)
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.
Another option for a name is curve448
. We could extract the EdDSA implementation/instantiation into ed448
at that point, which would follow how curve25519-dalek
/ed25519-dalek
are structured.
@tarcieri what's the blockers for moving this forward, given CI is green now? |
@tarcieri what would be the best place for me to put a |
I have an impl here as a reference btw: https://github.com/crate-crypto/x448 |
@kevaundray very nice, so I guess we just need to update that to the latest version of this 448 crate. Do you want to keep that crate under your management and update it, or should we move it into rustcrypto as well? |
I think it would make sense to move it to rustcrypto as well for completeness if you haven't made an implementation |
@dignifiedquire I'd like to do a final review and won't have time to do that for about a week |
|
||
[dependencies] | ||
crypto-bigint = { version = "0.6.0-rc.3", features = ["hybrid-array"], default-features = false } | ||
crypto_signature = { version = "2.3.0-pre.6", default-features = false, features = ["digest", "rand_core"], optional = true, package = "signature" } |
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 put this on the pre release for signature
and [email protected]
we will run into the issue that this is going to be unusable as in RustCrypto/signatures#930
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.
Let’s get this merged as-is and follow up on 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.
It’s also not the same problem as this crate has existing releases with older deps whereas ml-dsa
/slh-dsa
do not
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.
fyi I made https://github.com/dignifiedquire/cx448/ based on this code, which I will publish for now, so I can use a more up to date version
elliptic-curve = { version = "0.14.0-rc.0", features = ["arithmetic", "bits", "hash2curve", "jwk", "pkcs8", "pem", "sec1"] } | ||
pkcs8 = { version = "0.10", features = ["alloc"], optional = true } | ||
rand_core = { version = "0.9", default-features = false } | ||
serdect = { version = "0.3.0", optional = true } |
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.
looks like this needs to be a prerelease version to compile
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.
huh?
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 tried updating x448
to use this version and am getting this
error: failed to select a version for `serdect`.
... required by package `elliptic-curve v0.14.0-rc.0`
... which satisfies dependency `elliptic-curve = "^0.14.0-rc.0"` of package `ed448 v0.17.0-pre.0 (https://github.com/mikelodder7/elliptic-curves#363ed9dc)`
... which satisfies git dependency `ed448` of package `x448 v0.6.0 (/Users/dignified/opensource/x448)`
versions that meet the requirements `=0.3.0-pre.0` are: 0.3.0-pre.0
all possible versions conflict with previously selected packages.
previously selected package `serdect v0.3.0`
... which satisfies dependency `serdect = "^0.3.0"` of package `ed448 v0.17.0-pre.0 (https://github.com/mikelodder7/elliptic-curves#363ed9dc)`
... which satisfies git dependency `ed448` of package `x448 v0.6.0 (/Users/dignified/opensource/x448)`
with these dependencies
ed448 = { git = "https://github.com/mikelodder7/elliptic-curves", features = ["zeroize"] }
rand_core = { version = "0.9", default-features = false, features = ["getrandom"] }
zeroize = { version = "1.8", default-features = false, optional = true }
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.
For now you'll also need:
[patch.crates-io]
elliptic-curve = { git = "https://github.com/RustCrypto/traits.git" }
(also rand_core
v0.9 doesn't have a getrandom
feature, it's os_rng
)
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 not use rand_core 0.8, rand_core introduced more dependencies.
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 tried to use this to implement decaf448 for voprf
, but wasn't able to get things to match the test vectors (see the specification).
I played around with it for quite a while and eventually got it working, see mikelodder7#2. But unfortunately this broke a bunch of tests, no surprise: I'm not a cryptographer and I don't know what I'm doing.
I also added a test with a single test vector from the OPRF specification just to show how and where it breaks. I'm happy to add a full OPRF test vector suite as in #503, #600 and #964 when it passes.
/// Construct a `Scalar` from a little-endian byte representation. | ||
pub fn from_bytes(bytes: &[u8; 56]) -> Scalar { | ||
Self(U448::from_le_slice(bytes)) | ||
} |
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 can produce invalid Scalar
s. Just missing modulo ORDER
.
pub fn hash<X>(msg: &[u8], dst: &[u8]) -> Self | ||
where | ||
X: for<'a> ExpandMsg<'a>, | ||
{ | ||
let mut random_bytes = Array::<u8, U84>::default(); | ||
let dst = [dst]; | ||
let mut expander = | ||
X::expand_message(&[msg], &dst, random_bytes.len()).expect("invalid dst"); | ||
expander.fill_bytes(&mut random_bytes); | ||
Self::from_okm(&random_bytes) | ||
} |
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.
The specification says to use 64 bytes here. An public method taking 64 bytes, like Scalar::from_bytes_mod_order_wide()
, would probably be useful as well.
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.
My assessment was incorrect here, the specification part I linked here is not related to the hash_to_field
implementation.
pub const DECAF_BASEPOINT: DecafPoint = DecafPoint(curve::twedwards::extended::ExtendedPoint { | ||
X: TWISTED_EDWARDS_BASE_POINT.X, | ||
Y: TWISTED_EDWARDS_BASE_POINT.Y, | ||
Z: TWISTED_EDWARDS_BASE_POINT.Z, | ||
T: TWISTED_EDWARDS_BASE_POINT.T, | ||
}); |
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.
While I have no idea why the twisted curve is used for the internal representation, at least the public DecafPoint::GENERATOR
has to be correct.
pub const DECAF_BASEPOINT: DecafPoint = DecafPoint(curve::twedwards::extended::ExtendedPoint { | |
X: TWISTED_EDWARDS_BASE_POINT.X, | |
Y: TWISTED_EDWARDS_BASE_POINT.Y, | |
Z: TWISTED_EDWARDS_BASE_POINT.Z, | |
T: TWISTED_EDWARDS_BASE_POINT.T, | |
}); | |
pub const DECAF_BASEPOINT: DecafPoint = DecafPoint(curve::twedwards::extended::ExtendedPoint { | |
X: FieldElement(ConstMontyType::new(&U448::from_be_hex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa955555555555555555555555555555555555555555555555555555555"))), | |
Y: FieldElement(ConstMontyType::new(&U448::from_be_hex("ae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed"))), | |
Z: FieldElement(ConstMontyType::new(&U448::from_u64(1))), | |
T: FieldElement(ConstMontyType::new(&U448::from_be_hex("696d84643374bace9d70983a12aa9d461da74d2d5c35e8d97ba72c3aba4450a5d29274229bd22c1d5e3a6474ee4ffb0e7a9e200a28eee402"))), | |
}); |
I got the definition of the base point from the specification.
This is covered in mikelodder7#2 (comment) as well.
} | ||
|
||
impl FromOkm for Scalar { | ||
type Length = U84; |
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 should be 64 bytes as well, see #1121 (comment).
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.
As pointed out in #1121 (comment), this is wrong.
Main motivation was that `decaf448` (RustCrypto/elliptic-curves#1121) requires `ExpandMsgXof` instead of `ExpandMsgXmd`. I was briefly tempted to add a `type Hash` to the `ExpandMsg` trait to be able to write `type ExpandMsg = ExpandMsg<Hash = Self::Hash>`. Otherwise it is possible to add a different hash in the `ExpandMsg` type: ```rust impl VoprfParamters for Fun128 { type Hash = Sha512; type ExpandMsg = ExpandMsgXmd<Sha256>; ... } ``` But I thought its a bit much. Let me know if you want me to add that.
I took a swab at a rebase of this PR in #1208 just because I needed ed448. I ended up converting some of it to primeorder. Hopefully that can help with getting this merged. |
That's a little weird since ed(wards)448 isn't a prime order curve |
This adds the Ed448-Goldilocks curve and signing implementation from the latest commit at Mikelodder7/Ed448-Goldilocks.