Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 31 additions & 23 deletions src/protocols/csidh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,27 @@ use std::fmt::Display;
use fp2::traits::Fp as FqTrait;

use crate::{
elliptic::{curve::Curve, point::PointX, projective_point::Point},
elliptic::{curve::Curve, point::PointX},
polynomial_ring::poly::Polynomial,
utilities::bn::{mul_bn_by_u64_vartime},
utilities::bn::{mul_bn_by_u64_vartime, bn_compare_vartime},
};

use rand_core::{CryptoRng, RngCore};

#[derive(Clone, Copy, Debug)]
pub struct CsidhParameters<const NUM_ELLS: usize> {
pub struct CsidhParameters<const NUM_ELLS: usize, const FSQRTP: usize> {
pub max_exponent: usize,
pub two_cofactor: usize,
pub primes: [u64; NUM_ELLS],
pub four_sqrt_p: [u64; FSQRTP],
}

pub struct Csidh<Fp: FqTrait, const NUM_ELLS: usize> {
pub struct Csidh<Fp: FqTrait, const NUM_ELLS: usize, const FSQRTP: usize> {
max_exponent: usize,
two_cofactor: usize,
base: Fp,
primes: [u64; NUM_ELLS],
pub four_sqrt_p: [u64; FSQRTP],
}

pub struct CsidhPrivateKey<const NUM_ELLS: usize> {
Expand Down Expand Up @@ -58,13 +60,14 @@ impl<Fp: FqTrait> PartialEq for CsidhPublicKey<Fp> {
}
}

impl<Fp: FqTrait, const NUM_ELLS: usize> Csidh<Fp, NUM_ELLS> {
pub const fn new(params: &CsidhParameters<NUM_ELLS>) -> Self {
impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize> Csidh<Fp, NUM_ELLS, FSQRTP> {
pub const fn new(params: &CsidhParameters<NUM_ELLS, FSQRTP>) -> Self {
Self {
max_exponent: params.max_exponent,
two_cofactor: params.two_cofactor,
base: Fp::ZERO,
primes: params.primes,
four_sqrt_p: params.four_sqrt_p,
}
}

Expand Down Expand Up @@ -215,22 +218,9 @@ impl<Fp: FqTrait, const NUM_ELLS: usize> Csidh<Fp, NUM_ELLS> {
}

fn verify<R: CryptoRng + RngCore>(&self, public_key: &CsidhPublicKey<Fp>, rng: &mut R) -> bool {
// todo: move to Fp params
let four_sqrt_p: [u64; 8] = [
0x17895e71e1a20b3f,
0x38d0cd95f8636a56,
0x142b9541e59682cd,
0x856f1399d91d6592,
0x0000000000000002,
0x0000000000000000,
0x0000000000000000,
0x0000000000000000,
];

let A24 = public_key.A + Fp::TWO;
let C24 = Fp::FOUR;


loop {
let mut P : [PointX<Fp>; NUM_ELLS] = [PointX::INFINITY ; NUM_ELLS];

Expand All @@ -239,12 +229,31 @@ impl<Fp: FqTrait, const NUM_ELLS: usize> Csidh<Fp, NUM_ELLS> {

Curve::<Fp>::xdbl_proj_iter(&A24, &C24, &mut P[0], self.two_cofactor);

let mut order = vec![1];

self.cofactor_multiples(&mut P, &A24, &C24, 0, NUM_ELLS);

break;
}
for i in (0..NUM_ELLS).rev() {
if P[i].is_zero() == u32::MAX {
continue;
}

P[i] = Curve::<Fp>::xmul_proj_u64_vartime(&A24, &C24, &P[i], self.primes[i]);

true
if P[i].is_zero() == 0 {
return false;
}

order = mul_bn_by_u64_vartime(&order[..], self.primes[i]);

println!("{:#?}", order);

match bn_compare_vartime(&order[..], &self.four_sqrt_p[..]) {
std::cmp::Ordering::Greater => return true,
_ => {},
}
}
}
}

pub fn keygen<R: CryptoRng + RngCore>(
Expand All @@ -264,7 +273,6 @@ impl<Fp: FqTrait, const NUM_ELLS: usize> Csidh<Fp, NUM_ELLS> {
private_key: &CsidhPrivateKey<NUM_ELLS>,
rng: &mut R,
) -> Result<CsidhPublicKey<Fp>, CsidhError> {
// todo: verify
match self.verify(public_key, rng) {
true => Ok(self.action(public_key, private_key, rng)),
false => Err(CsidhError::PublicKeyVerificationError),
Expand Down
14 changes: 12 additions & 2 deletions src/protocols/csidh_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,22 @@ mod csidh_512 {
283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 587,
];

pub const CSIDH_PARAMS: CsidhParameters<NUM_PRIMES> = CsidhParameters {
const FOUR_SQRT_P: [u64; 5] = [
0x17895e71e1a20b3f,
0x38d0cd95f8636a56,
0x142b9541e59682cd,
0x856f1399d91d6592,
0x0000000000000002,
];


pub const CSIDH_PARAMS: CsidhParameters<NUM_PRIMES, 5> = CsidhParameters {
max_exponent: MAX_EXPONENT,
two_cofactor: COFACTOR,
primes: PRIMES,
four_sqrt_p: FOUR_SQRT_P,
Copy link
Owner

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

Copy link
Author

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.

Copy link
Owner

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

Copy link
Author

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).

Copy link
Owner

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)...

Copy link
Owner

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 $4 \sqrt{p}$ as a 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?

Copy link
Author

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.

};
}

pub const CSIDH_512: Csidh<Csidh512, { csidh_512::NUM_PRIMES }> =
pub const CSIDH_512: Csidh<Csidh512, { csidh_512::NUM_PRIMES }, 5> =
Csidh::new(&csidh_512::CSIDH_PARAMS);
24 changes: 24 additions & 0 deletions src/utilities/bn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,27 @@ pub fn factorisation_to_bn_vartime(factorisation: &[(usize, usize)]) -> Vec<u64>
}
n
}

pub fn bn_compare_vartime(x: &[u64], y: &[u64]) -> std::cmp::Ordering {
let len1 = x.len();
let len2 = y.len();

// Wenn eines der Arrays länger ist, ist es sicher größer.
if len1 > len2 {
return std::cmp::Ordering::Greater;
} else if len1 < len2 {
return std::cmp::Ordering::Less;
}

// Wenn die Längen gleich sind, vergleiche jedes Element.
for i in (0..len1).rev() {
if x[i] > y[i] {
return std::cmp::Ordering::Greater;
} else if x[i] < y[i] {
return std::cmp::Ordering::Less;
}
}

// Wenn alle Elemente gleich sind, sind die Arrays gleich.
std::cmp::Ordering::Equal
}