-
Notifications
You must be signed in to change notification settings - Fork 166
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
use kyber keys with different libraries #448
Comments
This is a known problem. See also the diagram in here: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/ You can try the |
Another thing I noticed is NaCl/Box expects the Montgomery representation of the curve points. There is a mapping between the Twisted Edward Curve Points and the Montgomery representation defined in RFC 7748. Might be worth looking at https://blog.filippo.io/using-ed25519-keys-for-encryption/ and https://libsodium.gitbook.io/doc/advanced/ed25519-curve25519. |
Thank you both for the quick response! I really appreciate it. @gnarula I've tried that previously and forgot to mention, sorry. to go from kyber/curve25519 through the formula described in filipo's blog that is. it didn't seem to work with NaCl/box, even though I managed to convert kyber's base point to the exact base point used in NaCl/box. I think it has to do with with the byte representation of the marshalled scalar. but I didn't managed to understand what. @ineiti I managed to ignore the fact that I don't have the seed, because I've found out that converting the secret key is expanding the seed into the scalar, and take it as the converted secret key: |
One thing I saw is that kyber always calculates the modulo of the scalar and points, whereas some libraries do not do that. I remember vaguely that BouncyCastle from Java didn't do it (might be wrong). You can create two scalars, zero and one, then subtract one from zero and see what you get. In Kyber you will get the (something something, always forget which constant it is), while in BouncyCastle you'll get And, yes, I think |
as far as I understood: by clamping I mean what is done in the function
( the name I found here: https://neilmadden.blog/2020/05/28/whats-the-curve25519-clamping-all-about/ ) |
Hmm, what if you try grabbing the []byte by using scalar.MarshalBinary() instead? IIRC, that method ensures the buffer contains the reduced value after taking the modulo. It's a shot in the dark though but my guess is NaCl/Box expects the scalar to be in the right range and errors out otherwise. Now this might not protect against small sub group attacks that clamping is used for and I'll leave that for others to share their thoughts on. PS: |
I don't think this is it: When converting the ed25519 key, if I take the I chose to grab specifically
I see, to be honest I started with curve25519, and when I didn't manage to convert i thought about just asking here, then I saw that ed25519 internal representation is similar to the code I saw in |
Do you mind sharing the code you're using for conversion? And possibly an example of the conversion succeeding/failing as well? |
Yes of course, https://play.golang.org/p/DrLXf9INeV_W Hopefully I didn't do anything foolish there. EDIT: it might fail while running on the website, because there are a lot of imports, and it timeout the running. |
I think it's got to do with Here's the output for a sample run:
You can see use std::convert::TryInto;
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::montgomery::MontgomeryPoint;
use curve25519_dalek::constants;
use hex;
use bincode;
fn main() {
let s1xhex = hex::decode("44d9deaadf0b8a85ba8f8e9dcc84e5c6a02d88844a6d024c331bb778fec78906").unwrap();
let s1x = Scalar::from_canonical_bytes(buf(&s1xhex)).unwrap();
let p2xhex = hex::decode("3eadd110930f44b5ff874d5c251889fe16c31828d958aaa3c253fcf6c5a12257").unwrap();
let p2x: MontgomeryPoint = bincode::deserialize(&buf(&p2xhex)).unwrap();
let product = s1x * p2x;
let product_buf = bincode::serialize(&product).unwrap();
let product_buf_hex = hex::encode(product_buf);
println!("product: {}", product_buf_hex);
}
fn buf(vec: &[u8]) -> [u8; 32] {
vec.try_into().expect("invalid length")
} and indeed, the product is I didn't dig much deep into |
I think I understand, thank you for the thorough inspection and explanation. a small question though: is it an issue that kyber isn't always clamping the scalar? |
Depends on whom you ask ;) The original kyber source has been created for people who don't care if they shoot themselves in the foot. So the code was as 'plain' as possible to the mathematical constructs. Clamping introduces some restrictions in what kind of scalars you can have. Which is good for security, but bad for some kind of experiments you might want to do. So there is the |
I see, I'm a non-expert so I'll tread with care :) |
I use kyber's DKG and attempted to reconstruct the secret key such that I'll be able to use it with NaCl/box.
Is there a proper way to convert kyber's keys to be able to work with other libraries?
What I've tried:
I've attempted to marshal keys generated by DKG with the followings suite:
NewBlakeSHA256Curve25519
. but this didn't work. Then I've made an attempt to useNewBlakeSHA256Ed25519
and convert the keys. After many attempts I've managed to use keys generated byNewBlakeSHA256Ed25519().NewKey()
with nacl/box, but when reconstructing a secret key gained by the DKG algorithm, the keys would not convert correctly, that is I wasn't able to use them with nacl/box.The text was updated successfully, but these errors were encountered: