Skip to content

Commit

Permalink
Merge pull request #34 from sebastienrousseau/feat/kyberlib
Browse files Browse the repository at this point in the history
v0.0.6
  • Loading branch information
sebastienrousseau authored May 12, 2024
2 parents a8d3285 + 3987945 commit 9bbbade
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ license = "MIT OR Apache-2.0"
name = "kyberlib"
readme = "README.md"
repository = "https://github.com/sebastienrousseau/kyberlib"
version = "0.0.5"
version = "0.0.6"

[dependencies]
# Dependencies for the library
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ To use the `kyberlib` library in your project, add the following to your

```toml
[dependencies]
kyberlib = "0.0.5"
kyberlib = "0.0.6"
```

Add the following to your `main.rs` file:
Expand Down Expand Up @@ -310,6 +310,6 @@ providing a lot of useful suggestions on how to improve this project.
[codecov-badge]: https://img.shields.io/codecov/c/github/sebastienrousseau/kyberlib?style=for-the-badge&token=oEisyTucB5 'Codecov'
[divider]: https://kura.pro/common/images/elements/divider.svg "divider"
[docs-badge]: https://img.shields.io/docsrs/kyberlib.svg?style=for-the-badge 'Docs.rs'
[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.5-orange.svg?style=for-the-badge 'Lib.rs'
[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.6-orange.svg?style=for-the-badge 'Lib.rs'
[license-badge]: https://img.shields.io/crates/l/kyberlib.svg?style=for-the-badge 'License'
[made-with-rust]: https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust 'Made With Rust'
2 changes: 1 addition & 1 deletion TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ A Robust Rust Library for CRYSTALS-Kyber Post-Quantum Cryptography
[crates-badge]: https://img.shields.io/crates/v/kyberlib.svg?style=for-the-badge 'Crates.io badge'
[divider]: https://via.placeholder.com/1024x1.png/d8dee4/FFFFFF?text=− "kyberlib's divider"
[docs-badge]: https://img.shields.io/docsrs/kyberlib.svg?style=for-the-badge 'Docs.rs badge'
[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.5-orange.svg?style=for-the-badge 'Lib.rs badge'
[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.6-orange.svg?style=for-the-badge 'Lib.rs badge'
[license-badge]: https://img.shields.io/crates/l/kyberlib.svg?style=for-the-badge 'License badge'
[made-with-rust-badge]: https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust 'Made With Rust badge'

Expand Down
41 changes: 31 additions & 10 deletions src/reference/poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ pub(crate) fn poly_compress(r: &mut [u8], a: Poly) {
let mut k = 0usize;
let mut u: i16;

// Compress_q(x, d) = ⌈(2ᵈ/q)x⌋ mod⁺ 2ᵈ
// = ⌊(2ᵈ/q)x+½⌋ mod⁺ 2ᵈ
// = ⌊((x << d) + q/2) / q⌋ mod⁺ 2ᵈ
// = DIV((x << d) + q/2, q) & ((1<<d) - 1)
//
// We approximate DIV(x, q) by computing (x*a)>>e, where a/(2^e) ≈ 1/q.
// For d in {10,11} we use 20,642,678/2^36, which computes division by x/q
// correctly for 0 ≤ x < 41,522,616, which fits (q << 11) + q/2 comfortably.
// For d in {4,5} we use 315/2^20, which doesn't compute division by x/q
// correctly for all inputs, but it's close enough that the end result
// of the compression is correct. The advantage is that we do not need
// to use a 64-bit intermediate value.
match KYBER_POLY_COMPRESSED_BYTES {
128 => {
#[allow(clippy::needless_range_loop)]
Expand All @@ -41,9 +53,11 @@ pub(crate) fn poly_compress(r: &mut [u8], a: Poly) {
// map to positive standard representatives
u = a.coeffs[8 * i + j];
u += (u >> 15) & KYBER_Q as i16;
t[j] = (((((u as u16) << 4) + KYBER_Q as u16 / 2)
/ KYBER_Q as u16)
& 15) as u8;
let mut tmp: u32 =
(((u as u16) << 4) + KYBER_Q as u16 / 2) as u32;
tmp *= 315;
tmp >>= 20;
t[j] = ((tmp as u16) & 15) as u8;
}
r[k] = t[0] | (t[1] << 4);
r[k + 1] = t[2] | (t[3] << 4);
Expand All @@ -59,9 +73,11 @@ pub(crate) fn poly_compress(r: &mut [u8], a: Poly) {
// map to positive standard representatives
u = a.coeffs[8 * i + j];
u += (u >> 15) & KYBER_Q as i16;
t[j] = (((((u as u32) << 5) + KYBER_Q as u32 / 2)
/ KYBER_Q as u32)
& 31) as u8;
let mut tmp: u32 =
((u as u32) << 5) + KYBER_Q as u32 / 2;
tmp *= 315;
tmp >>= 20;
t[j] = ((tmp as u16) & 31) as u8;
}
r[k] = t[0] | (t[1] << 5);
r[k + 1] = (t[1] >> 3) | (t[2] << 2) | (t[3] << 7);
Expand Down Expand Up @@ -324,14 +340,19 @@ pub(crate) fn poly_frommsg(r: &mut Poly, msg: &[u8]) {
/// Arguments: - [u8] msg: output message
/// - const poly *a: input polynomial
pub(crate) fn poly_tomsg(msg: &mut [u8], a: Poly) {
let mut t;
let mut t: u32;
#[allow(clippy::needless_range_loop)]
for i in 0..KYBER_N / 8 {
msg[i] = 0;
for j in 0..8 {
t = a.coeffs[8 * i + j];
t += (t >> 15) & KYBER_Q as i16;
t = (((t << 1) + KYBER_Q as i16 / 2) / KYBER_Q as i16) & 1;
t = a.coeffs[8 * i + j] as u32;

t <<= 1;
t = t.wrapping_add(1665);
t = t.wrapping_mul(80635);
t >>= 28;
t &= 1;

msg[i] |= (t << j) as u8;
}
}
Expand Down
36 changes: 19 additions & 17 deletions src/reference/polyvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ pub(crate) fn polyvec_compress(r: &mut [u8], a: Polyvec) {
let mut idx = 0usize;
for i in 0..KYBER_SECURITY_PARAMETER {
for j in 0..KYBER_N / 8 {
for k in 0..8 {
t[k] = a.vec[i].coeffs[8 * j + k] as u16;
t[k] = t[k].wrapping_add(
(((t[k] as i16) >> 15) & KYBER_Q as i16) as u16,
for (k, t_k) in t.iter_mut().enumerate() {
*t_k = a.vec[i].coeffs[8 * j + k] as u16;
*t_k = t_k.wrapping_add(
((((*t_k as i16) >> 15) & KYBER_Q as i16)
as u16),
);
t[k] = (((((t[k] as u32) << 11)
+ KYBER_Q as u32 / 2)
/ KYBER_Q as u32)
& 0x7ff) as u16;
let mut tmp: u64 =
((*t_k as u64) << 11) + (KYBER_Q as u64 / 2);
tmp *= 20642679;
tmp >>= 36;
*t_k = (tmp as u16) & 0x7ff;
}
r[idx] = (t[0]) as u8;
r[idx + 1] = ((t[0] >> 8) | (t[1] << 3)) as u8;
Expand All @@ -61,16 +63,16 @@ pub(crate) fn polyvec_compress(r: &mut [u8], a: Polyvec) {
let mut idx = 0usize;
for i in 0..KYBER_SECURITY_PARAMETER {
for j in 0..KYBER_N / 4 {
for (k, item) in t.iter_mut().enumerate() {
*item = a.vec[i].coeffs[4 * j + k] as u16;
*item = item.wrapping_add(
(((*item as i16) >> 15) & KYBER_Q as i16)
as u16,
for (k, t_k) in t.iter_mut().enumerate() {
*t_k = a.vec[i].coeffs[4 * j + k] as u16;
*t_k = t_k.wrapping_add(
(((*t_k as i16) >> 15) & KYBER_Q as i16) as u16,
);
*item = (((((*item as u32) << 10)
+ KYBER_Q as u32 / 2)
/ KYBER_Q as u32)
& 0x3ff) as u16;
let mut tmp: u64 =
((*t_k as u64) << 10) + (KYBER_Q as u64 / 2);
tmp *= 20642679;
tmp >>= 36;
*t_k = (tmp as u16) & 0x3ff;
}
r[idx] = (t[0]) as u8;
r[idx + 1] = ((t[0] >> 8) | (t[1] << 2)) as u8;
Expand Down
9 changes: 9 additions & 0 deletions tests/test_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ fn test_kyber_lib_error_display() {
error.to_string(),
"The secret and public key given does not match."
);
let error = KyberLibError::InvalidLength;
assert_eq!(
error.to_string(),
"The length of the input buffer is invalid."
);
}

#[test]
Expand All @@ -54,6 +59,10 @@ fn test_kyber_lib_error_partial_eq() {
let error2 = KyberLibError::InvalidKey;
assert_eq!(error1, error2);

let error1 = KyberLibError::InvalidLength;
let error2 = KyberLibError::InvalidLength;
assert_eq!(error1, error2);

let error1 = KyberLibError::InvalidInput;
let error2 = KyberLibError::Decapsulation;
assert_ne!(error1, error2);
Expand Down

0 comments on commit 9bbbade

Please sign in to comment.