-
Notifications
You must be signed in to change notification settings - Fork 1
CSIDH #1
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: main
Are you sure you want to change the base?
CSIDH #1
Conversation
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.
Some small comments, but otherwise thank you so much!
src/elliptic/curve.rs
Outdated
let Y = V * XZ; | ||
let ok = Y.is_square(); | ||
|
||
(P, ok) |
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 function should simply be a call to rand_point
to get a valid point, then we should use to_pointx
. Something like:
pub fn rand_pointx<R: CryptoRng + RngCore>(&self, rng: &mut R) -> PointX {
let P = Self::rand_point(rng);
P.to_pointx()
}
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 see that this method uses failure for the direction in CSIDH
reading some more, but I think this then really needs to be a method for CSIDH rather than on the Curve type, as wanting a point on the twist instead of the curve seems a little esoteric?
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.
Maybe we want something like rand_point
on the Csidh type and then we return `P, twist) to make it obvious what we're doing for this case?
src/protocols/csidh.rs
Outdated
|
||
#[derive(Clone, Copy, Debug)] | ||
pub struct CsidhParameters<const COUNT: usize> { | ||
pub num_primes: usize, |
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.
is num_primes
not just the same as COUNT
?
src/protocols/csidh.rs
Outdated
|
||
} | ||
|
||
// // For extra safty, assert the kernel is indeed of the correct degree |
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 extra safty, assert the kernel is indeed of the correct degree | |
// // For extra safety, assert the kernel is indeed of the correct degree |
|
||
// check if the kernel is of the correct degree | ||
// if not we skip it and try again on an new round | ||
if K.is_zero() == u32::MAX { |
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.
Feels like this continue should somehow be linked in to cofactor clearing, otherwise you might have P = 0
after an evaluation and yet you spend all that time cofactor clearing only to exit afterwards.
src/protocols/csidh_parameters.rs
Outdated
]; | ||
|
||
pub const CSIDH_PARAMS: CsidhParameters<NUM_PRIMES> = CsidhParameters { | ||
num_primes: NUM_PRIMES, |
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.
yeah this can be cleaned up, we dont need
num_primesas we can just use
NUM_PRIMES`
src/protocols/csidh.rs
Outdated
let (mut P, direction) = curve.rand_pointX(rng); | ||
let direction = direction == 0; | ||
|
||
// clear cofactor |
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.
// clear cofactor | |
// clear 2^e cofactor |
src/protocols/csidh.rs
Outdated
private_key: &CsidhPrivateKey<COUNT>, | ||
rng: &mut R,) -> CsidhPublicKey<Fp> { | ||
|
||
// todo: verify |
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.
shall we ust multiply by (p+1) a bunch of times to check supersingularity?
I'm back from leave now, did you have time to work on the comments, or would you like me to merge as is and do edits myself? |
src/elliptic/point.rs
Outdated
} | ||
|
||
/// Return a new random X only point. | ||
pub fn rand_point<R: CryptoRng + RngCore>(rng: &mut R) -> PointX<Fq> { |
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 doesnt always return a valid point on the curve... I think we should just delete this for now as it might be confusing?
src/protocols/csidh.rs
Outdated
use rand_core::{CryptoRng, RngCore}; | ||
|
||
#[derive(Clone, Copy, Debug)] | ||
pub struct CsidhParameters<const COUNT: usize> { |
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.
maybe rename to PRIMES or PRIME_COUNT?
src/fields/csidh.rs
Outdated
|
||
|
||
|
||
fp2::define_fp2_from_modulus!( |
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.
We dont need the extension, right? We can use define_fp_core
https://docs.rs/fp2/latest/fp2/macro.define_fp_core.html
max_exponent: MAX_EXPONENT, | ||
two_cofactor: COFACTOR, | ||
primes: PRIMES, | ||
four_sqrt_p: FOUR_SQRT_P, |
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.
Cant we have this value as a Fp
and then avoid the need for , 5
? Similar to how we have constants in the sidh impl
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.
Yeah, this part is quite ugly.
The issue is that we need 4sqrt(p) as a bigint (bn), not as a Fp, in the verification, to check against the order of the random point.
The cleanest way would probably be to have a struct for bn.
I'll try to come up with something.
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.
We do we need it to be a big number? For scalar multiplication? One option would be to use a Fp element and then encode this to bytes for scalar multiplication? Another, yes, would be to make a BN type
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.
We only use this constant to check if the order of a point is > 4sqrt(p).
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.
Oh I see, this is alg 2 of (https://eprint.iacr.org/2022/880.pdf)...
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 the "best" method at the moment is have Fp
type in the structure and then in verify we can do something like
bound = bytes_to_bn_vartime(&self.four_sqrt_p.encode())
where &self.four_sqrt_p.encode()
will have type &[u8]
and bytes_to_bn_vartime
can convert from base 2^8 to base 2^64?
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 ended up adding a small Bn struct as a wrapper.
Let me know what you think about this approach.
If you think it's suitable I can also extend the struct.
src/protocols/csidh.rs
Outdated
|
||
// if RHS i a sqrt, it is on the curve | ||
let RHS = (Cxx+four_Ax-two_Cx+(*C24))*x; | ||
let (_, is_sqrt) = RHS.sqrt(); |
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 four_Ax = tmp+tmp; | ||
// projective curve: x^3C+4Ax^2−2x^2C+XC | ||
let tmp = *A24*x; | ||
let four_Ax = tmp+tmp+tmp+tmp; |
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.
we have a mul4()
method available in fp2_rs
let four_Ax = tmp+tmp+tmp+tmp; | ||
let tmp = *C24*x; | ||
let Cxx = tmp*x; | ||
let two_Cx = tmp+tmp; |
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.
Same here, we have a mul2()
src/protocols/csidh.rs
Outdated
let A24 = public_key.A + Fp::TWO; | ||
let C24 = Fp::FOUR; | ||
|
||
let fsqrtp = &self.four_sqrt_p.limbs[..self.four_sqrt_p.len]; |
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 looks like we might want to make a method out of it? maybe a Bn
to_slice()
?
0x856f1399d91d6592, | ||
0x0000000000000002, | ||
]; | ||
0x0000000000000000, |
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 the extra 0x00
?
src/utilities/bn.rs
Outdated
|
||
|
||
// This is a small wrapper to use a bn as constant | ||
const BN_MAXLIMBS : usize = 8; |
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.
oooh this is why... Maybe we should use a vector and dynamically allocate? This could be refactored later I suppose though.
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.
Vectors and constants don't like each other much.
What about putting Bn behind a macro, similar to Fp?
It's quite a bit of overhead for a single constant, but it should be the cleanest solution and might be helpful for other protocols.
In this PR, we provide a simplified implementation of the CSIDH protocol using the CSIDH-512 parameter set.
It is simplified in the sense that it is not fully optimized, but focuses on the readability of the different steps in the protocol.
Further todos: