diff --git a/CHANGELOG.md b/CHANGELOG.md index c0cea53..68df4d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0 - 2023-8-31 + +* Added: Wasm compilation feature and npm package + ## 0.1.1 - 2023-2-2 * Refactor: Consolidated symmetric modules diff --git a/Cargo.toml b/Cargo.toml index 8f0dd79..382e8bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pqc_dilithium" -version = "0.1.1" +version = "0.2.0" authors = ["Mitchell Berry "] description = "A post-quantum cryptographic signature scheme based on the hardness of lattice problems over module lattices" edition = "2018" @@ -21,7 +21,7 @@ version = "0.8.5" features = ["getrandom"] [dev-dependencies] -pqc_core = {version = "0.1.0", features = ["load"]} +pqc_core = {version = "0.3.0", features = ["load"]} [target.'cfg(bench)'.dev-dependencies.criterion] criterion = "0.4.0" diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..2bf0d7c --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,40 @@ +# Release Checklist + +`VERSION=v0.0.0` + +1. New branch `git checkout -b release_$VERSION` + +2. Bump any dependencies in **Cargo.toml** + +3. Run tests: + ```bash + ./tests/test_matrix.sh; + ./tests/wasm.js; + ``` + +4. Bump version in **Cargo.toml** + +5. Update **changelog.md** + +6. `cargo fmt` + +7. `wasm-pack build -- --features wasm` + +8. Fix autogenerated **pkg/package.json**: + * name - Replace *pqc_dilithium* with *pqc-dilithium* + * description - Revert line back to old description + +9. `git commit -a -m "release $VERSION"` + +10. `git tag $VERSION -m "Version release"` + +11. `git push --atomic origin release_$VERSION $VERSION` + +12. Open PR to master, confirm all CI checks pass, merge PR + +13. `cargo publish` + +14. `npm publish` + +15. `git checkout master && git branch -d release_$VERSION` + diff --git a/benches/api.rs b/benches/api.rs index 772ddb3..b7ccfbb 100644 --- a/benches/api.rs +++ b/benches/api.rs @@ -1,8 +1,7 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use pqc_dilithium::*; -fn sign_small_msg(c: &mut Criterion) -{ +fn sign_small_msg(c: &mut Criterion) { let keys = Keypair::generate(); let msg = "Hello".as_bytes(); c.bench_function("Sign Small Message", |b| { @@ -10,8 +9,7 @@ fn sign_small_msg(c: &mut Criterion) }); } -fn verify_small_msg(c: &mut Criterion) -{ +fn verify_small_msg(c: &mut Criterion) { let keys = Keypair::generate(); let msg = "Hello".as_bytes(); let sig = keys.sign(msg); diff --git a/pkg/README.md b/pkg/README.md index 74feb29..2e9de5f 100644 --- a/pkg/README.md +++ b/pkg/README.md @@ -16,7 +16,9 @@ It is recommended to use Dilithium in a hybrid system alongside a traditional si --- ## Installation -This repository is not available on npm at this moment +```shell +npm i pqc-dilithium +``` ## Usage diff --git a/pkg/package.json b/pkg/package.json index bd2bb78..1f5edde 100644 --- a/pkg/package.json +++ b/pkg/package.json @@ -1,10 +1,10 @@ { - "name": "pqc_dilithium", + "name": "pqc-dilithium", "collaborators": [ "Mitchell Berry " ], - "description": "A post-quantum cryptographic signature scheme based on the hardness of lattice problems over module lattices", - "version": "0.1.1", + "description": "A post-quantum cryptographic signature scheme written in Rust and compiled to a Wasm binary", + "version": "0.2.0", "license": "MIT OR Apache-2.0", "repository": { "type": "git", diff --git a/src/aes256ctr.rs b/src/aes256ctr.rs index 26ba46b..165589a 100644 --- a/src/aes256ctr.rs +++ b/src/aes256ctr.rs @@ -1,15 +1,12 @@ pub const AES256CTR_BLOCKBYTES: usize = 64; -pub struct Aes256ctrCtx -{ +pub struct Aes256ctrCtx { pub sk_exp: [u64; 120], pub ivw: [u32; 16], } -impl Default for Aes256ctrCtx -{ - fn default() -> Self - { +impl Default for Aes256ctrCtx { + fn default() -> Self { Self { sk_exp: [0u64; 120], ivw: [0u32; 16], @@ -17,16 +14,14 @@ impl Default for Aes256ctrCtx } } -fn br_dec32le(src: &[u8]) -> u32 -{ +fn br_dec32le(src: &[u8]) -> u32 { src[0] as u32 | (src[1] as u32) << 8 | (src[2] as u32) << 16 | (src[3] as u32) << 24 } -fn br_range_dec32le(v: &mut [u32], mut num: usize, src: &[u8]) -{ +fn br_range_dec32le(v: &mut [u32], mut num: usize, src: &[u8]) { let mut v_idx: usize = 0; let mut src_idx: usize = 0; while num > 0 { @@ -37,22 +32,19 @@ fn br_range_dec32le(v: &mut [u32], mut num: usize, src: &[u8]) } } -fn br_swap32(mut x: u32) -> u32 -{ +fn br_swap32(mut x: u32) -> u32 { x = ((x & 0x00FF00FFu32) << 8) | ((x >> 8) & 0x00FF00FFu32); (x << 16) | (x >> 16) } -fn br_enc32le(dst: &mut [u8], x: u32) -{ +fn br_enc32le(dst: &mut [u8], x: u32) { dst[0] = x as u8; dst[1] = (x >> 8) as u8; dst[2] = (x >> 16) as u8; dst[3] = (x >> 24) as u8; } -fn br_range_enc32le(dst: &mut [u8], v: &[u32], mut num: usize) -{ +fn br_range_enc32le(dst: &mut [u8], v: &[u32], mut num: usize) { let mut v_idx = 0; let mut dst_idx = 0; while num > 0 { @@ -63,8 +55,7 @@ fn br_range_enc32le(dst: &mut [u8], v: &[u32], mut num: usize) } } -fn br_aes_ct64_bitslice_sbox(q: &mut [u64]) -{ +fn br_aes_ct64_bitslice_sbox(q: &mut [u64]) { // This S-box implementation is a straightforward translation of // the circuit described by Boyar and Peralta in "A new // combinational logic minimization technique with applications @@ -213,31 +204,26 @@ fn br_aes_ct64_bitslice_sbox(q: &mut [u64]) q[0] = s7; } -fn swapn(cl: u64, ch: u64, s: usize, x: u64, y: &mut u64) -> u64 -{ +fn swapn(cl: u64, ch: u64, s: usize, x: u64, y: &mut u64) -> u64 { let a = x; let b = *y; *y = ((a & ch) >> (s)) | (b & ch); // update y (a & cl) | ((b & cl) << s) // return x } -fn swap2(x: u64, y: &mut u64) -> u64 -{ +fn swap2(x: u64, y: &mut u64) -> u64 { swapn(0x5555555555555555u64, 0xAAAAAAAAAAAAAAAAu64, 1, x, y) } -fn swap4(x: u64, y: &mut u64) -> u64 -{ +fn swap4(x: u64, y: &mut u64) -> u64 { swapn(0x3333333333333333u64, 0xCCCCCCCCCCCCCCCCu64, 2, x, y) } -fn swap8(x: u64, y: &mut u64) -> u64 -{ +fn swap8(x: u64, y: &mut u64) -> u64 { swapn(0x0F0F0F0F0F0F0F0Fu64, 0xF0F0F0F0F0F0F0F0u64, 4, x, y) } -fn br_aes_ct64_ortho(q: &mut [u64]) -{ +fn br_aes_ct64_ortho(q: &mut [u64]) { q[0] = swap2(q[0], &mut q[1]); q[2] = swap2(q[2], &mut q[3]); q[4] = swap2(q[4], &mut q[5]); @@ -254,8 +240,7 @@ fn br_aes_ct64_ortho(q: &mut [u64]) q[3] = swap8(q[3], &mut q[7]); } -fn br_aes_ct64_interleave_in(q0: &mut u64, q1: &mut u64, w: &[u32]) -{ +fn br_aes_ct64_interleave_in(q0: &mut u64, q1: &mut u64, w: &[u32]) { let mut x0 = w[0] as u64; let mut x1 = w[1] as u64; let mut x2 = w[2] as u64; @@ -280,8 +265,7 @@ fn br_aes_ct64_interleave_in(q0: &mut u64, q1: &mut u64, w: &[u32]) *q1 = x1 | (x3 << 8); } -fn br_aes_ct64_interleave_out(w: &mut [u32], q0: u64, q1: u64) -{ +fn br_aes_ct64_interleave_out(w: &mut [u32], q0: u64, q1: u64) { let mut x0 = q0 & 0x00FF00FF00FF00FFu64; let mut x1 = q1 & 0x00FF00FF00FF00FFu64; let mut x2 = (q0 >> 8) & 0x00FF00FF00FF00FFu64; @@ -300,8 +284,7 @@ fn br_aes_ct64_interleave_out(w: &mut [u32], q0: u64, q1: u64) w[3] = x3 as u32 | (x3 >> 16) as u32; } -fn sub_word(x: u32) -> u32 -{ +fn sub_word(x: u32) -> u32 { let mut q = [0u64; 8]; q[0] = x as u64; br_aes_ct64_ortho(&mut q); @@ -313,8 +296,7 @@ fn sub_word(x: u32) -> u32 const RCON: [u32; 10] = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36]; -fn br_aes_ct64_keysched(comp_skey: &mut [u64], key: &[u8]) -{ +fn br_aes_ct64_keysched(comp_skey: &mut [u64], key: &[u8]) { let (mut j, mut k) = (0usize, 0usize); let mut skey = [0u32; 60]; let key_len = 32usize; @@ -363,8 +345,7 @@ fn br_aes_ct64_keysched(comp_skey: &mut [u64], key: &[u8]) } } -fn br_aes_ct64_skey_expand(skey: &mut [u64], comp_skey: &[u64]) -{ +fn br_aes_ct64_skey_expand(skey: &mut [u64], comp_skey: &[u64]) { const N: usize = 15 << 1; let mut u = 0; let mut v = 0; @@ -393,8 +374,7 @@ fn br_aes_ct64_skey_expand(skey: &mut [u64], comp_skey: &[u64]) } } -fn add_round_key(q: &mut [u64], sk: &[u64]) -{ +fn add_round_key(q: &mut [u64], sk: &[u64]) { q[0] ^= sk[0]; q[1] ^= sk[1]; q[2] ^= sk[2]; @@ -405,8 +385,7 @@ fn add_round_key(q: &mut [u64], sk: &[u64]) q[7] ^= sk[7]; } -fn shift_rows(q: &mut [u64]) -{ +fn shift_rows(q: &mut [u64]) { for x in q.iter_mut() { *x = (*x & 0x000000000000FFFF) | ((*x & 0x00000000FFF00000) >> 4) @@ -418,13 +397,11 @@ fn shift_rows(q: &mut [u64]) } } -fn rotr32(x: u64) -> u64 -{ +fn rotr32(x: u64) -> u64 { (x << 32) | (x >> 32) } -fn mix_columns(q: &mut [u64]) -{ +fn mix_columns(q: &mut [u64]) { let q0 = q[0]; let q1 = q[1]; let q2 = q[2]; @@ -452,14 +429,12 @@ fn mix_columns(q: &mut [u64]) q[7] = q6 ^ r6 ^ r7 ^ rotr32(q7 ^ r7); } -fn inc4_be(x: u32) -> u32 -{ +fn inc4_be(x: u32) -> u32 { let t = br_swap32(x) + 4; br_swap32(t) } -fn aes_ctr4x(out: &mut [u8], ivw: &mut [u32], sk_exp: &[u64]) -{ +fn aes_ctr4x(out: &mut [u8], ivw: &mut [u32], sk_exp: &[u64]) { let mut w = [0u32; 16]; w.copy_from_slice(&ivw); let mut q = [0u64; 8]; @@ -493,15 +468,13 @@ fn aes_ctr4x(out: &mut [u8], ivw: &mut [u32], sk_exp: &[u64]) ivw[15] = inc4_be(ivw[15]); } -fn br_aes_ct64_ctr_init(sk_exp: &mut [u64], key: &[u8]) -{ +fn br_aes_ct64_ctr_init(sk_exp: &mut [u64], key: &[u8]) { let mut skey = [0u64; 30]; br_aes_ct64_keysched(&mut skey, key); br_aes_ct64_skey_expand(sk_exp, &skey); } -pub fn aes256ctr_init(s: &mut Aes256ctrCtx, key: &[u8], nonce: [u8; 12]) -{ +pub fn aes256ctr_init(s: &mut Aes256ctrCtx, key: &[u8], nonce: [u8; 12]) { br_aes_ct64_ctr_init(&mut s.sk_exp, &key); br_range_dec32le(&mut s.ivw, 3, &nonce); let mut slice = [0u32; 3]; @@ -519,8 +492,7 @@ pub fn aes256ctr_squeezeblocks( out: &mut [u8], mut nblocks: u64, s: &mut Aes256ctrCtx, -) -{ +) { let mut idx = 0; while nblocks > 0 { aes_ctr4x(&mut out[idx..], &mut s.ivw, &s.sk_exp); diff --git a/src/api.rs b/src/api.rs index 0074fe2..3a29494 100644 --- a/src/api.rs +++ b/src/api.rs @@ -2,29 +2,24 @@ use crate::params::{PUBLICKEYBYTES, SECRETKEYBYTES, SIGNBYTES}; use crate::sign::*; #[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub struct Keypair -{ +pub struct Keypair { pub public: [u8; PUBLICKEYBYTES], secret: [u8; SECRETKEYBYTES], } /// Secret key elided -impl std::fmt::Debug for Keypair -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result - { +impl std::fmt::Debug for Keypair { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "public: {:?}\nsecret: ", self.public) } } -pub enum SignError -{ +pub enum SignError { Input, Verify, } -impl Keypair -{ +impl Keypair { /// Explicitly expose secret key /// ``` /// # use pqc_dilithium::*; @@ -32,8 +27,7 @@ impl Keypair /// let secret_key = keys.expose_secret(); /// assert!(secret_key.len() == SECRETKEYBYTES); /// ``` - pub fn expose_secret(&self) -> &[u8] - { + pub fn expose_secret(&self) -> &[u8] { &self.secret } @@ -46,8 +40,7 @@ impl Keypair /// assert!(keys.public.len() == PUBLICKEYBYTES); /// assert!(keys.expose_secret().len() == SECRETKEYBYTES); /// ``` - pub fn generate() -> Keypair - { + pub fn generate() -> Keypair { let mut public = [0u8; PUBLICKEYBYTES]; let mut secret = [0u8; SECRETKEYBYTES]; crypto_sign_keypair(&mut public, &mut secret, None); @@ -64,8 +57,7 @@ impl Keypair /// let sig = keys.sign(&msg); /// assert!(sig.len() == SIGNBYTES); /// ``` - pub fn sign(&self, msg: &[u8]) -> [u8; SIGNBYTES] - { + pub fn sign(&self, msg: &[u8]) -> [u8; SIGNBYTES] { let mut sig = [0u8; SIGNBYTES]; crypto_sign_signature(&mut sig, msg, &self.secret); sig @@ -86,8 +78,7 @@ pub fn verify( sig: &[u8], msg: &[u8], public_key: &[u8], -) -> Result<(), SignError> -{ +) -> Result<(), SignError> { if sig.len() != SIGNBYTES { return Err(SignError::Input); } diff --git a/src/fips202.rs b/src/fips202.rs index 6a3d749..a0ccede 100644 --- a/src/fips202.rs +++ b/src/fips202.rs @@ -7,17 +7,14 @@ pub const SHAKE256_RATE: usize = 136; const NROUNDS: usize = 24; #[derive(Copy, Clone)] -pub struct KeccakState -{ +pub struct KeccakState { pub s: [u64; 25], pub pos: usize, } // Replaces init functions -impl Default for KeccakState -{ - fn default() -> Self - { +impl Default for KeccakState { + fn default() -> Self { KeccakState { s: [0u64; 25], pos: 0usize, @@ -25,23 +22,19 @@ impl Default for KeccakState } } -impl KeccakState -{ - pub fn init(&mut self) - { +impl KeccakState { + pub fn init(&mut self) { self.s.fill(0); self.pos = 0; } } -fn rol(a: u64, offset: u64) -> u64 -{ +fn rol(a: u64, offset: u64) -> u64 { (a << offset) ^ (a >> (64 - offset)) } /// Load 8 bytes into uint64_t in little-endian order/ -pub fn load64(x: &[u8]) -> u64 -{ +pub fn load64(x: &[u8]) -> u64 { let mut r = 0u64; for i in 0..8 { r |= (x[i] as u64) << (8 * i); @@ -50,8 +43,7 @@ pub fn load64(x: &[u8]) -> u64 } /// Store a 64-bit integer to array of 8 bytes in little-endian order -pub fn store64(x: &mut [u8], u: u64) -{ +pub fn store64(x: &mut [u8], u: u64) { for i in 0..8 { x[i] = (u >> 8 * i) as u8; } @@ -86,8 +78,7 @@ const KECCAKF_ROUNDCONSTANTS: [u64; NROUNDS] = [ ]; /// The Keccak F1600 Permutation -pub fn keccakf1600_statepermute(state: &mut [u64]) -{ +pub fn keccakf1600_statepermute(state: &mut [u64]) { //copyFromState(A, state) let mut aba = state[0]; let mut abe = state[1]; @@ -340,8 +331,7 @@ fn keccak_absorb( r: usize, input: &[u8], mut inlen: usize, -) -{ +) { let mut idx = 0; let mut pos = state.pos; while pos + inlen >= r { @@ -363,8 +353,7 @@ fn keccak_absorb( } /// Finalize absorb step. -fn keccak_finalize(s: &mut [u64; 25], pos: usize, r: usize, p: u8) -{ +fn keccak_finalize(s: &mut [u64; 25], pos: usize, r: usize, p: u8) { s[pos / 8] ^= (p as u64) << 8 * (pos % 8); s[r / 8 - 1] ^= 1u64 << 63; } @@ -380,8 +369,7 @@ fn keccak_squeeze( s: &mut [u64; 25], mut pos: usize, r: usize, -) -> usize -{ +) -> usize { while outlen != 0 { if pos == r { keccakf1600_statepermute(s); @@ -409,8 +397,7 @@ fn keccak_absorb_once( input: &[u8], mut inlen: usize, p: u8, -) -{ +) { s.fill(0); let mut idx = 0; while inlen >= r { @@ -439,8 +426,7 @@ fn keccak_squeezeblocks( mut nblocks: usize, s: &mut [u64], r: usize, -) -{ +) { let mut idx = 0usize; while nblocks > 0 { keccakf1600_statepermute(s); @@ -454,15 +440,13 @@ fn keccak_squeezeblocks( /// Description: Absorb step of the SHAKE128 XOF; incremental. #[cfg(not(feature = "aes"))] -pub fn shake128_absorb(state: &mut KeccakState, input: &[u8], inlen: usize) -{ +pub fn shake128_absorb(state: &mut KeccakState, input: &[u8], inlen: usize) { keccak_absorb(state, SHAKE128_RATE, input, inlen); } /// Finalize absorb step of the SHAKE128 XOF. #[cfg(not(feature = "aes"))] -pub fn shake128_finalize(state: &mut KeccakState) -{ +pub fn shake128_finalize(state: &mut KeccakState) { keccak_finalize(&mut state.s, state.pos as usize, SHAKE128_RATE, 0x1F); state.pos = SHAKE128_RATE; } @@ -476,34 +460,37 @@ pub fn shake128_squeezeblocks( output: &mut [u8], nblocks: usize, s: &mut KeccakState, -) -{ +) { keccak_squeezeblocks(output, nblocks, &mut s.s, SHAKE128_RATE); } /// Absorb step of the SHAKE256 XOF; incremental. -pub fn shake256_absorb(state: &mut KeccakState, input: &[u8], inlen: usize) -{ +pub fn shake256_absorb(state: &mut KeccakState, input: &[u8], inlen: usize) { keccak_absorb(state, SHAKE256_RATE, input, inlen); } /// Finalize absorb step of the SHAKE256 XOF.*/ -pub fn shake256_finalize(state: &mut KeccakState) -{ +pub fn shake256_finalize(state: &mut KeccakState) { keccak_finalize(&mut state.s, state.pos, SHAKE256_RATE, 0x1F); state.pos = SHAKE256_RATE; } ///Squeeze step of SHAKE256 XOF. Squeezes arbitraily many /// bytes. Can be called multiple times to keep squeezing. -pub fn shake256_squeeze(out: &mut [u8], outlen: usize, state: &mut KeccakState) -{ +pub fn shake256_squeeze( + out: &mut [u8], + outlen: usize, + state: &mut KeccakState, +) { state.pos = keccak_squeeze(out, outlen, &mut state.s, state.pos, SHAKE256_RATE); } /// Initialize, absorb into and finalize SHAKE256 XOF; non-incremental. -pub fn shake256_absorb_once(state: &mut KeccakState, input: &[u8], inlen: usize) -{ +pub fn shake256_absorb_once( + state: &mut KeccakState, + input: &[u8], + inlen: usize, +) { keccak_absorb_once(&mut state.s, SHAKE256_RATE, input, inlen, 0x1F); state.pos = SHAKE256_RATE; } @@ -516,8 +503,7 @@ pub fn shake256_squeezeblocks( out: &mut [u8], nblocks: usize, state: &mut KeccakState, -) -{ +) { keccak_squeezeblocks(out, nblocks, &mut state.s, SHAKE256_RATE); } @@ -527,8 +513,7 @@ pub fn shake256( mut outlen: usize, input: &[u8], inlen: usize, -) -{ +) { let mut state = KeccakState::default(); shake256_absorb_once(&mut state, input, inlen); diff --git a/src/ntt.rs b/src/ntt.rs index 21bb05c..09c495a 100644 --- a/src/ntt.rs +++ b/src/ntt.rs @@ -42,8 +42,7 @@ pub const ZETAS: [i32; N] = [ /// additions or subtractions. Output vector is in bitreversed order. // /// Arguments: - uint32_t p[N]: input/output coefficient array -pub fn ntt(a: &mut [i32]) -{ +pub fn ntt(a: &mut [i32]) { let mut j; let mut k = 0usize; let mut len = 128; @@ -76,8 +75,7 @@ pub fn ntt(a: &mut [i32]) /// absolute value. // /// Arguments: - uint32_t p[N]: input/output coefficient array -pub fn invntt_tomont(a: &mut [i32]) -{ +pub fn invntt_tomont(a: &mut [i32]) { let mut j; let mut k = 256usize; let mut len = 1; @@ -106,11 +104,9 @@ pub fn invntt_tomont(a: &mut [i32]) } } -mod tests -{ +mod tests { #[test] - fn ntt() - { + fn ntt() { let mut a = [ -1, 1, -4, -3, -4, 4, 1, 1, 2, 4, 1, 2, -2, 3, 1, 0, -3, 1, -1, -2, 4, -4, -1, -3, -4, -3, 3, -3, -1, 0, 0, 2, 3, -4, 3, 4, 1, -3, -1, 3, 0, 0, @@ -168,8 +164,7 @@ mod tests } #[test] - fn invntt_tomont() - { + fn invntt_tomont() { let mut a = [ -410121, -3439227, -1510274, 1543151, -2293562, -1024787, -1768713, 3416108, -1829266, -39421, 1553720, 383193, -1303564, 2601404, 178534, diff --git a/src/packing.rs b/src/packing.rs index a27618a..561ffbf 100644 --- a/src/packing.rs +++ b/src/packing.rs @@ -1,8 +1,7 @@ use crate::{params::*, poly::*, polyvec::*, SignError}; /// Bit-pack public key pk = (rho, t1). -pub fn pack_pk(pk: &mut [u8], rho: &[u8], t1: &Polyveck) -{ +pub fn pack_pk(pk: &mut [u8], rho: &[u8], t1: &Polyveck) { pk[..SEEDBYTES].copy_from_slice(&rho[..SEEDBYTES]); for i in 0..K { polyt1_pack(&mut pk[SEEDBYTES + i * POLYT1_PACKEDBYTES..], &t1.vec[i]); @@ -10,8 +9,7 @@ pub fn pack_pk(pk: &mut [u8], rho: &[u8], t1: &Polyveck) } /// Unpack public key pk = (rho, t1). -pub fn unpack_pk(rho: &mut [u8], t1: &mut Polyveck, pk: &[u8]) -{ +pub fn unpack_pk(rho: &mut [u8], t1: &mut Polyveck, pk: &[u8]) { rho[..SEEDBYTES].copy_from_slice(&pk[..SEEDBYTES]); for i in 0..K { polyt1_unpack(&mut t1.vec[i], &pk[SEEDBYTES + i * POLYT1_PACKEDBYTES..]) @@ -27,8 +25,7 @@ pub fn pack_sk( t0: &Polyveck, s1: &Polyvecl, s2: &Polyveck, -) -{ +) { let mut idx = 0usize; sk[idx..SEEDBYTES].copy_from_slice(&rho[0..SEEDBYTES]); @@ -64,8 +61,7 @@ pub fn unpack_sk( s1: &mut Polyvecl, s2: &mut Polyveck, sk: &[u8], -) -{ +) { let mut idx = 0usize; rho[..SEEDBYTES].copy_from_slice(&sk[..SEEDBYTES]); @@ -93,8 +89,7 @@ pub fn unpack_sk( } /// Bit-pack signature sig = (c, z, h). -pub fn pack_sig(sig: &mut [u8], c: Option<&[u8]>, z: &Polyvecl, h: &Polyveck) -{ +pub fn pack_sig(sig: &mut [u8], c: Option<&[u8]>, z: &Polyvecl, h: &Polyveck) { let mut idx = 0usize; if let Some(challenge) = c { @@ -128,8 +123,7 @@ pub fn unpack_sig( z: &mut Polyvecl, h: &mut Polyveck, sig: &[u8], -) -> Result<(), SignError> -{ +) -> Result<(), SignError> { let mut idx = 0usize; c[..SEEDBYTES].copy_from_slice(&sig[..SEEDBYTES]); diff --git a/src/poly.rs b/src/poly.rs index f5d5852..24b59c9 100644 --- a/src/poly.rs +++ b/src/poly.rs @@ -5,23 +5,19 @@ use crate::{ const D_SHL: i32 = 1i32 << (D - 1); #[derive(Copy, Clone)] -pub struct Poly -{ +pub struct Poly { pub coeffs: [i32; N], } -impl Default for Poly -{ - fn default() -> Self - { +impl Default for Poly { + fn default() -> Self { Poly { coeffs: [0i32; N] } } } /// Inplace reduction of all coefficients of polynomial to /// representative in [0,2*Q]. -pub fn poly_reduce(a: &mut Poly) -{ +pub fn poly_reduce(a: &mut Poly) { for i in 0..N { a.coeffs[i] = reduce32(a.coeffs[i]); } @@ -29,16 +25,14 @@ pub fn poly_reduce(a: &mut Poly) /// For all coefficients of in/out polynomial add Q if /// coefficient is negative. -pub fn poly_caddq(a: &mut Poly) -{ +pub fn poly_caddq(a: &mut Poly) { for i in 0..N { a.coeffs[i] = caddq(a.coeffs[i]); } } /// Add polynomials. No modular reduction is performed. -pub fn poly_add(c: &mut Poly, b: &Poly) -{ +pub fn poly_add(c: &mut Poly, b: &Poly) { for i in 0..N { c.coeffs[i] = c.coeffs[i] + b.coeffs[i]; } @@ -47,8 +41,7 @@ pub fn poly_add(c: &mut Poly, b: &Poly) /// Subtract polynomials. Assumes coefficients of second input /// polynomial to be less than 2*Q. No modular reduction is /// performed. -pub fn poly_sub(c: &mut Poly, b: &Poly) -{ +pub fn poly_sub(c: &mut Poly, b: &Poly) { for i in 0..N { c.coeffs[i] = c.coeffs[i] - b.coeffs[i]; } @@ -56,8 +49,7 @@ pub fn poly_sub(c: &mut Poly, b: &Poly) /// Multiply polynomial by 2^D without modular reduction. Assumes /// input coefficients to be less than 2^{32-D}. -pub fn poly_shiftl(a: &mut Poly) -{ +pub fn poly_shiftl(a: &mut Poly) { for i in 0..N { a.coeffs[i] <<= D; } @@ -65,16 +57,14 @@ pub fn poly_shiftl(a: &mut Poly) /// Inplace forward NTT. Output coefficients can be up to /// 16*Q larger than input coefficients. -pub fn poly_ntt(a: &mut Poly) -{ +pub fn poly_ntt(a: &mut Poly) { ntt(&mut a.coeffs); } /// Inplace inverse NTT and multiplication by 2^{32}. /// Input coefficients need to be less than 2*Q. /// Output coefficients are less than 2*Q. -pub fn poly_invntt_tomont(a: &mut Poly) -{ +pub fn poly_invntt_tomont(a: &mut Poly) { invntt_tomont(&mut a.coeffs); } @@ -82,8 +72,7 @@ pub fn poly_invntt_tomont(a: &mut Poly) /// representation and multiplication of resulting polynomial /// by 2^{-32}. Output coefficients are less than 2*Q if input /// coefficient are less than 22*Q. -pub fn poly_pointwise_montgomery(c: &mut Poly, a: &Poly, b: &Poly) -{ +pub fn poly_pointwise_montgomery(c: &mut Poly, a: &Poly, b: &Poly) { for i in 0..N { c.coeffs[i] = montgomery_reduce((a.coeffs[i] as i64) * b.coeffs[i] as i64); } @@ -93,8 +82,7 @@ pub fn poly_pointwise_montgomery(c: &mut Poly, a: &Poly, b: &Poly) /// compute c0, c1 such that c mod Q = c1*2^D + c0 /// with -2^{D-1} < c0 <= 2^{D-1}. Assumes coefficients to be /// standard representatives. -pub fn poly_power2round(a1: &mut Poly, a0: &mut Poly) -{ +pub fn poly_power2round(a1: &mut Poly, a0: &mut Poly) { for i in 0..N { a1.coeffs[i] = power2round(a1.coeffs[i], &mut a0.coeffs[i]); } @@ -105,8 +93,7 @@ pub fn poly_power2round(a1: &mut Poly, a0: &mut Poly) /// with -ALPHA/2 < c0 <= ALPHA/2 except c1 = (Q-1)/ALPHA where we /// set c1 = 0 and -ALPHA/2 <= c0 = c mod Q - Q < 0. /// Assumes coefficients to be standard representatives. -pub fn poly_decompose(a1: &mut Poly, a0: &mut Poly) -{ +pub fn poly_decompose(a1: &mut Poly, a0: &mut Poly) { for i in 0..N { a1.coeffs[i] = decompose(&mut a0.coeffs[i], a1.coeffs[i]); } @@ -115,8 +102,7 @@ pub fn poly_decompose(a1: &mut Poly, a0: &mut Poly) /// Compute hint polynomial. The coefficients of which indicate /// whether the low bits of the corresponding coefficient of /// the input polynomial overflow into the high bits. -pub fn poly_make_hint(h: &mut Poly, a0: &Poly, a1: &Poly) -> i32 -{ +pub fn poly_make_hint(h: &mut Poly, a0: &Poly, a1: &Poly) -> i32 { let mut s = 0i32; for i in 0..N { h.coeffs[i] = make_hint(a0.coeffs[i], a1.coeffs[i]) as i32; @@ -130,8 +116,7 @@ pub fn poly_make_hint(h: &mut Poly, a0: &Poly, a1: &Poly) -> i32 /// Arguments: - poly *b: pointer to output polynomial with corrected high bits /// - const poly *a: pointer to input polynomial /// - const poly *h: pointer to input hint polynomial -pub fn poly_use_hint(b: &mut Poly, h: &Poly) -{ +pub fn poly_use_hint(b: &mut Poly, h: &Poly) { for i in 0..N { b.coeffs[i] = use_hint(b.coeffs[i], h.coeffs[i] as u8); } @@ -140,8 +125,7 @@ pub fn poly_use_hint(b: &mut Poly, h: &Poly) /// Check infinity norm of polynomial against given bound. /// Assumes input coefficients to be standard representatives. /// Returns 0 if norm is strictly smaller than B and 1 otherwise. -pub fn poly_chknorm(a: &Poly, b: i32) -> u8 -{ +pub fn poly_chknorm(a: &Poly, b: i32) -> u8 { // It is ok to leak which coefficient violates the bound since // the probability for each coefficient is independent of secret // data but we must not leak the sign of the centralized representative. @@ -166,8 +150,7 @@ pub fn poly_chknorm(a: &Poly, b: i32) -> u8 /// performing rejection sampling on array of random bytes. /// Returns number of sampled coefficients. Can be smaller than len if not enough /// random bytes were given. -pub fn rej_uniform(a: &mut [i32], len: u32, buf: &[u8], buflen: usize) -> u32 -{ +pub fn rej_uniform(a: &mut [i32], len: u32, buf: &[u8], buflen: usize) -> u32 { let (mut ctr, mut pos) = (0usize, 0usize); let mut t; while ctr < len as usize && pos + 3 <= buflen { @@ -193,8 +176,7 @@ const POLY_UNIFORM_NBLOCKS: usize = /// Sample polynomial with uniformly random coefficients /// in [0, Q-1] by performing rejection sampling using the /// output stream of SHAKE256(seed|nonce) or AES256CTR(seed,nonce). -pub fn poly_uniform(a: &mut Poly, seed: &[u8], nonce: u16) -{ +pub fn poly_uniform(a: &mut Poly, seed: &[u8], nonce: u16) { let mut buflen = POLY_UNIFORM_NBLOCKS * STREAM128_BLOCKBYTES; let mut buf = [0u8; POLY_UNIFORM_NBLOCKS * STREAM128_BLOCKBYTES + 2]; let mut state = Stream128State::default(); @@ -222,8 +204,7 @@ pub fn poly_uniform(a: &mut Poly, seed: &[u8], nonce: u16) /// Sample uniformly random coefficients in [-ETA, ETA] by /// performing rejection sampling using array of random bytes. -pub fn rej_eta(a: &mut [i32], len: usize, buf: &[u8], buflen: usize) -> u32 -{ +pub fn rej_eta(a: &mut [i32], len: usize, buf: &[u8], buflen: usize) -> u32 { let (mut ctr, mut pos) = (0usize, 0usize); let (mut t0, mut t1); while ctr < len && pos < buflen { @@ -265,8 +246,7 @@ const POLY_UNIFORM_ETA_NBLOCKS: usize = if ETA == 2 { (227 + STREAM256_BLOCKBYTES - 1) / STREAM256_BLOCKBYTES }; -pub fn poly_uniform_eta(a: &mut Poly, seed: &[u8], nonce: u16) -{ +pub fn poly_uniform_eta(a: &mut Poly, seed: &[u8], nonce: u16) { let buflen = POLY_UNIFORM_ETA_NBLOCKS * STREAM256_BLOCKBYTES; let mut buf = [0u8; POLY_UNIFORM_ETA_NBLOCKS * STREAM256_BLOCKBYTES]; let mut state = Stream256State::default(); @@ -297,8 +277,7 @@ const POLY_UNIFORM_GAMMA1_NBLOCKS: usize = /// in [-(GAMMA1 - 1), GAMMA1 - 1] by performing rejection /// sampling on output stream of SHAKE256(seed|nonce) /// or AES256CTR(seed,nonce). -pub fn poly_uniform_gamma1(a: &mut Poly, seed: &[u8], nonce: u16) -{ +pub fn poly_uniform_gamma1(a: &mut Poly, seed: &[u8], nonce: u16) { let mut buf = [0u8; POLY_UNIFORM_GAMMA1_NBLOCKS * STREAM256_BLOCKBYTES]; let mut state = Stream256State::default(); @@ -314,8 +293,7 @@ pub fn poly_uniform_gamma1(a: &mut Poly, seed: &[u8], nonce: u16) /// Implementation of H. Samples polynomial with TAU nonzero /// coefficients in {-1,1} using the output stream of /// SHAKE256(seed). -pub fn poly_challenge(c: &mut Poly, seed: &[u8]) -{ +pub fn poly_challenge(c: &mut Poly, seed: &[u8]) { let mut _signs = 0u64; let mut buf = [0u8; SHAKE256_RATE]; let mut state = KeccakState::default(); //shake256_init @@ -351,8 +329,7 @@ pub fn poly_challenge(c: &mut Poly, seed: &[u8]) /// Bit-pack polynomial with coefficients in [-ETA,ETA]. /// Input coefficients are assumed to lie in [Q-ETA,Q+ETA]. -pub fn polyeta_pack(r: &mut [u8], a: &Poly) -{ +pub fn polyeta_pack(r: &mut [u8], a: &Poly) { let mut t = [0u8; 8]; if ETA == 2 { for i in 0..N / 8 { @@ -379,8 +356,7 @@ pub fn polyeta_pack(r: &mut [u8], a: &Poly) } /// Unpack polynomial with coefficients in [-ETA,ETA]. -pub fn polyeta_unpack(r: &mut Poly, a: &[u8]) -{ +pub fn polyeta_unpack(r: &mut Poly, a: &[u8]) { if ETA == 2 { for i in 0..N / 8 { r.coeffs[8 * i + 0] = (a[3 * i + 0] & 0x07) as i32; @@ -415,8 +391,7 @@ pub fn polyeta_unpack(r: &mut Poly, a: &[u8]) /// Bit-pack polynomial t1 with coefficients fitting in 10 bits. /// Input coefficients are assumed to be standard representatives. -pub fn polyt1_pack(r: &mut [u8], a: &Poly) -{ +pub fn polyt1_pack(r: &mut [u8], a: &Poly) { for i in 0..N / 4 { r[5 * i + 0] = (a.coeffs[4 * i + 0] >> 0) as u8; r[5 * i + 1] = @@ -431,8 +406,7 @@ pub fn polyt1_pack(r: &mut [u8], a: &Poly) /// Unpack polynomial t1 with 9-bit coefficients. /// Output coefficients are standard representatives. -pub fn polyt1_unpack(r: &mut Poly, a: &[u8]) -{ +pub fn polyt1_unpack(r: &mut Poly, a: &[u8]) { for i in 0..N / 4 { r.coeffs[4 * i + 0] = (((a[5 * i + 0] >> 0) as u32 | (a[5 * i + 1] as u32) << 8) @@ -450,8 +424,7 @@ pub fn polyt1_unpack(r: &mut Poly, a: &[u8]) } /// Bit-pack polynomial t0 with coefficients in [-2^{D-1}, 2^{D-1}]. -pub fn polyt0_pack(r: &mut [u8], a: &Poly) -{ +pub fn polyt0_pack(r: &mut [u8], a: &Poly) { let mut t = [0i32; 8]; for i in 0..N / 8 { @@ -489,8 +462,7 @@ pub fn polyt0_pack(r: &mut [u8], a: &Poly) /// Unpack polynomial t0 with coefficients in ]-2^{D-1}, 2^{D-1}]. /// Output coefficients lie in ]Q-2^{D-1},Q+2^{D-1}]. -pub fn polyt0_unpack(r: &mut Poly, a: &[u8]) -{ +pub fn polyt0_unpack(r: &mut Poly, a: &[u8]) { for i in 0..N / 8 { r.coeffs[8 * i + 0] = a[13 * i + 0] as i32; r.coeffs[8 * i + 0] |= (a[13 * i + 1] as i32) << 8; @@ -542,8 +514,7 @@ pub fn polyt0_unpack(r: &mut Poly, a: &[u8]) /// Bit-pack polynomial z with coefficients /// in [-(GAMMA1 - 1), GAMMA1 - 1]. /// Input coefficients are assumed to be standard representatives.* -pub fn polyz_pack(r: &mut [u8], a: &Poly) -{ +pub fn polyz_pack(r: &mut [u8], a: &Poly) { let mut t = [0i32; 4]; if GAMMA1 == (1 << 17) { for i in 0..N / 4 { @@ -583,8 +554,7 @@ pub fn polyz_pack(r: &mut [u8], a: &Poly) /// Unpack polynomial z with coefficients /// in [-(GAMMA1 - 1), GAMMA1 - 1]. /// Output coefficients are standard representatives. -pub fn polyz_unpack(r: &mut Poly, a: &[u8]) -{ +pub fn polyz_unpack(r: &mut Poly, a: &[u8]) { if GAMMA1 == (1 << 17) { for i in 0..N / 4 { r.coeffs[4 * i + 0] = a[9 * i + 0] as i32; @@ -632,8 +602,7 @@ pub fn polyz_unpack(r: &mut Poly, a: &[u8]) /// Bit-pack polynomial w1 with coefficients in [0, 15]. /// Input coefficients are assumed to be standard representatives. -pub fn polyw1_pack(r: &mut [u8], a: &Poly) -{ +pub fn polyw1_pack(r: &mut [u8], a: &Poly) { if GAMMA2 == (Q - 1) / 88 { for i in 0..N / 4 { r[3 * i + 0] = a.coeffs[4 * i + 0] as u8; diff --git a/src/polyvec.rs b/src/polyvec.rs index 8427a8d..b177906 100644 --- a/src/polyvec.rs +++ b/src/polyvec.rs @@ -2,15 +2,12 @@ use crate::params::*; use crate::poly::*; #[derive(Copy, Clone)] -pub struct Polyveck -{ +pub struct Polyveck { pub vec: [Poly; K], } -impl Default for Polyveck -{ - fn default() -> Self - { +impl Default for Polyveck { + fn default() -> Self { Polyveck { vec: [Poly::default(); K], } @@ -18,15 +15,12 @@ impl Default for Polyveck } #[derive(Copy, Clone)] -pub struct Polyvecl -{ +pub struct Polyvecl { pub vec: [Poly; L], } -impl Default for Polyvecl -{ - fn default() -> Self - { +impl Default for Polyvecl { + fn default() -> Self { Polyvecl { vec: [Poly::default(); L], } @@ -37,8 +31,7 @@ impl Default for Polyvecl /// random coefficients a_{i,j} by performing rejection /// sampling on the output stream of SHAKE128(rho|j|i) /// or AES256CTR(rho,j|i). -pub fn polyvec_matrix_expand(mat: &mut [Polyvecl], rho: &[u8]) -{ +pub fn polyvec_matrix_expand(mat: &mut [Polyvecl], rho: &[u8]) { for i in 0..K { for j in 0..L { poly_uniform(&mut mat[i].vec[j], rho, ((i << 8) + j) as u16); @@ -50,8 +43,7 @@ pub fn polyvec_matrix_pointwise_montgomery( t: &mut Polyveck, mat: &[Polyvecl], v: &Polyvecl, -) -{ +) { for i in 0..K { polyvecl_pointwise_acc_montgomery(&mut t.vec[i], &mat[i], v); } @@ -59,22 +51,19 @@ pub fn polyvec_matrix_pointwise_montgomery( //*********** Vectors of polynomials of length L **************************** -pub fn polyvecl_uniform_eta(v: &mut Polyvecl, seed: &[u8], mut nonce: u16) -{ +pub fn polyvecl_uniform_eta(v: &mut Polyvecl, seed: &[u8], mut nonce: u16) { for i in 0..L { poly_uniform_eta(&mut v.vec[i], seed, nonce); nonce += 1; } } -pub fn polyvecl_uniform_gamma1(v: &mut Polyvecl, seed: &[u8], nonce: u16) -{ +pub fn polyvecl_uniform_gamma1(v: &mut Polyvecl, seed: &[u8], nonce: u16) { for i in 0..L { poly_uniform_gamma1(&mut v.vec[i], seed, L_U16 * nonce + i as u16); } } -pub fn polyvecl_reduce(v: &mut Polyvecl) -{ +pub fn polyvecl_reduce(v: &mut Polyvecl) { for i in 0..L { poly_reduce(&mut v.vec[i]); } @@ -82,8 +71,7 @@ pub fn polyvecl_reduce(v: &mut Polyvecl) /// Add vectors of polynomials of length L. /// No modular reduction is performed. -pub fn polyvecl_add(w: &mut Polyvecl, v: &Polyvecl) -{ +pub fn polyvecl_add(w: &mut Polyvecl, v: &Polyvecl) { for i in 0..L { poly_add(&mut w.vec[i], &v.vec[i]); } @@ -91,15 +79,13 @@ pub fn polyvecl_add(w: &mut Polyvecl, v: &Polyvecl) /// Forward NTT of all polynomials in vector of length L. Output /// coefficients can be up to 16*Q larger than input coefficients.* -pub fn polyvecl_ntt(v: &mut Polyvecl) -{ +pub fn polyvecl_ntt(v: &mut Polyvecl) { for i in 0..L { poly_ntt(&mut v.vec[i]); } } -pub fn polyvecl_invntt_tomont(v: &mut Polyvecl) -{ +pub fn polyvecl_invntt_tomont(v: &mut Polyvecl) { for i in 0..L { poly_invntt_tomont(&mut v.vec[i]); } @@ -109,8 +95,7 @@ pub fn polyvecl_pointwise_poly_montgomery( r: &mut Polyvecl, a: &Poly, v: &Polyvecl, -) -{ +) { for i in 0..L { poly_pointwise_montgomery(&mut r.vec[i], a, &v.vec[i]); } @@ -125,8 +110,7 @@ pub fn polyvecl_pointwise_acc_montgomery( w: &mut Poly, u: &Polyvecl, v: &Polyvecl, -) -{ +) { let mut t = Poly::default(); poly_pointwise_montgomery(w, &u.vec[0], &v.vec[0]); for i in 1..L { @@ -139,8 +123,7 @@ pub fn polyvecl_pointwise_acc_montgomery( /// Assumes input coefficients to be standard representatives. /// Returns 0 if norm of all polynomials is strictly smaller than B and 1 /// otherwise. -pub fn polyvecl_chknorm(v: &Polyvecl, bound: i32) -> u8 -{ +pub fn polyvecl_chknorm(v: &Polyvecl, bound: i32) -> u8 { for i in 0..L { if poly_chknorm(&v.vec[i], bound) > 0 { return 1; @@ -151,8 +134,7 @@ pub fn polyvecl_chknorm(v: &Polyvecl, bound: i32) -> u8 //*********** Vectors of polynomials of length K **************************** -pub fn polyveck_uniform_eta(v: &mut Polyveck, seed: &[u8], mut nonce: u16) -{ +pub fn polyveck_uniform_eta(v: &mut Polyveck, seed: &[u8], mut nonce: u16) { for i in 0..K { poly_uniform_eta(&mut v.vec[i], seed, nonce); nonce += 1 @@ -161,8 +143,7 @@ pub fn polyveck_uniform_eta(v: &mut Polyveck, seed: &[u8], mut nonce: u16) /// Reduce coefficients of polynomials in vector of length K /// to representatives in [0,2*Q]. -pub fn polyveck_reduce(v: &mut Polyveck) -{ +pub fn polyveck_reduce(v: &mut Polyveck) { for i in 0..K { poly_reduce(&mut v.vec[i]); } @@ -170,8 +151,7 @@ pub fn polyveck_reduce(v: &mut Polyveck) /// For all coefficients of polynomials in vector of length K /// add Q if coefficient is negative. -pub fn polyveck_caddq(v: &mut Polyveck) -{ +pub fn polyveck_caddq(v: &mut Polyveck) { for i in 0..K { poly_caddq(&mut v.vec[i]); } @@ -179,8 +159,7 @@ pub fn polyveck_caddq(v: &mut Polyveck) /// Add vectors of polynomials of length K. /// No modular reduction is performed. -pub fn polyveck_add(w: &mut Polyveck, v: &Polyveck) -{ +pub fn polyveck_add(w: &mut Polyveck, v: &Polyveck) { for i in 0..K { poly_add(&mut w.vec[i], &v.vec[i]); } @@ -189,8 +168,7 @@ pub fn polyveck_add(w: &mut Polyveck, v: &Polyveck) /// Subtract vectors of polynomials of length K. /// Assumes coefficients of polynomials in second input vector /// to be less than 2*Q. No modular reduction is performed. -pub fn polyveck_sub(w: &mut Polyveck, v: &Polyveck) -{ +pub fn polyveck_sub(w: &mut Polyveck, v: &Polyveck) { for i in 0..K { poly_sub(&mut w.vec[i], &v.vec[i]); } @@ -198,8 +176,7 @@ pub fn polyveck_sub(w: &mut Polyveck, v: &Polyveck) /// Multiply vector of polynomials of Length K by 2^D without modular /// reduction. Assumes input coefficients to be less than 2^{32-D}. -pub fn polyveck_shiftl(v: &mut Polyveck) -{ +pub fn polyveck_shiftl(v: &mut Polyveck) { for i in 0..K { poly_shiftl(&mut v.vec[i]); } @@ -207,8 +184,7 @@ pub fn polyveck_shiftl(v: &mut Polyveck) /// Forward NTT of all polynomials in vector of length K. Output /// coefficients can be up to 16*Q larger than input coefficients. -pub fn polyveck_ntt(v: &mut Polyveck) -{ +pub fn polyveck_ntt(v: &mut Polyveck) { for i in 0..K { poly_ntt(&mut v.vec[i]); } @@ -217,8 +193,7 @@ pub fn polyveck_ntt(v: &mut Polyveck) /// Inverse NTT and multiplication by 2^{32} of polynomials /// in vector of length K. Input coefficients need to be less /// than 2*Q. -pub fn polyveck_invntt_tomont(v: &mut Polyveck) -{ +pub fn polyveck_invntt_tomont(v: &mut Polyveck) { for i in 0..K { poly_invntt_tomont(&mut v.vec[i]); } @@ -228,8 +203,7 @@ pub fn polyveck_pointwise_poly_montgomery( r: &mut Polyveck, a: &Poly, v: &Polyveck, -) -{ +) { for i in 0..K { poly_pointwise_montgomery(&mut r.vec[i], a, &v.vec[i]); } @@ -240,8 +214,7 @@ pub fn polyveck_pointwise_poly_montgomery( // /// Returns 0 if norm of all polynomials are strictly smaller than B and 1 /// otherwise. -pub fn polyveck_chknorm(v: &Polyveck, bound: i32) -> u8 -{ +pub fn polyveck_chknorm(v: &Polyveck, bound: i32) -> u8 { for i in 0..K { if poly_chknorm(&v.vec[i], bound) > 0 { return 1; @@ -254,8 +227,7 @@ pub fn polyveck_chknorm(v: &Polyveck, bound: i32) -> u8 /// compute a0, a1 such that a mod Q = a1*2^D + a0 /// with -2^{D-1} < a0 <= 2^{D-1}. Assumes coefficients to be /// standard representatives. -pub fn polyveck_power2round(v1: &mut Polyveck, v0: &mut Polyveck) -{ +pub fn polyveck_power2round(v1: &mut Polyveck, v0: &mut Polyveck) { for i in 0..K { poly_power2round(&mut v1.vec[i], &mut v0.vec[i]); } @@ -266,8 +238,7 @@ pub fn polyveck_power2round(v1: &mut Polyveck, v0: &mut Polyveck) /// with -ALPHA/2 < a0 <= ALPHA/2 except a1 = (Q-1)/ALPHA where we /// set a1 = 0 and -ALPHA/2 <= a0 = a mod Q - Q < 0. /// Assumes coefficients to be standard representatives. -pub fn polyveck_decompose(v1: &mut Polyveck, v0: &mut Polyveck) -{ +pub fn polyveck_decompose(v1: &mut Polyveck, v0: &mut Polyveck) { for i in 0..K { poly_decompose(&mut v1.vec[i], &mut v0.vec[i]); } @@ -276,9 +247,11 @@ pub fn polyveck_decompose(v1: &mut Polyveck, v0: &mut Polyveck) /// Compute hint vector. /// /// Returns number of 1 bits. -pub fn polyveck_make_hint(h: &mut Polyveck, v0: &Polyveck, v1: &Polyveck) - -> i32 -{ +pub fn polyveck_make_hint( + h: &mut Polyveck, + v0: &Polyveck, + v1: &Polyveck, +) -> i32 { let mut s = 0i32; for i in 0..K { s += poly_make_hint(&mut h.vec[i], &v0.vec[i], &v1.vec[i]); @@ -287,15 +260,13 @@ pub fn polyveck_make_hint(h: &mut Polyveck, v0: &Polyveck, v1: &Polyveck) } /// Use hint vector to correct the high bits of input vector. -pub fn polyveck_use_hint(w: &mut Polyveck, h: &Polyveck) -{ +pub fn polyveck_use_hint(w: &mut Polyveck, h: &Polyveck) { for i in 0..K { poly_use_hint(&mut w.vec[i], &h.vec[i]); } } -pub fn polyveck_pack_w1(r: &mut [u8], w1: &Polyveck) -{ +pub fn polyveck_pack_w1(r: &mut [u8], w1: &Polyveck) { for i in 0..K { polyw1_pack(&mut r[i * POLYW1_PACKEDBYTES..], &w1.vec[i]); } diff --git a/src/randombytes.rs b/src/randombytes.rs index 8b773e9..b67a2fc 100644 --- a/src/randombytes.rs +++ b/src/randombytes.rs @@ -1,6 +1,5 @@ use rand::prelude::*; -pub fn randombytes(x: &mut [u8], len: usize) -{ +pub fn randombytes(x: &mut [u8], len: usize) { thread_rng().fill_bytes(&mut x[..len]) } diff --git a/src/reduce.rs b/src/reduce.rs index a083f38..6d25685 100644 --- a/src/reduce.rs +++ b/src/reduce.rs @@ -6,8 +6,7 @@ pub const QINV: i32 = 58728449; // q^(-1) mod 2^32 /// compute r \equiv a*2^{-32} (mod Q) such that -Q < r < Q. /// /// Returns r. -pub fn montgomery_reduce(a: i64) -> i32 -{ +pub fn montgomery_reduce(a: i64) -> i32 { let mut t = (a as i32).wrapping_mul(QINV) as i64; t = (a as i64 - t * Q as i64) >> 32; t as i32 @@ -17,8 +16,7 @@ pub fn montgomery_reduce(a: i64) -> i32 /// compute r \equiv a (mod Q) such that -6283009 <= r <= 6283007. // /// Returns r. -pub fn reduce32(a: i32) -> i32 -{ +pub fn reduce32(a: i32) -> i32 { let mut t = (a + (1 << 22)) >> 23; t = a - t * Q as i32; t @@ -27,7 +25,6 @@ pub fn reduce32(a: i32) -> i32 /// Add Q if input coefficient is negative. /// /// Returns r. -pub fn caddq(a: i32) -> i32 -{ +pub fn caddq(a: i32) -> i32 { a + ((a >> 31) & Q as i32) } diff --git a/src/rounding.rs b/src/rounding.rs index 9644bb9..14ce3af 100644 --- a/src/rounding.rs +++ b/src/rounding.rs @@ -5,8 +5,7 @@ use crate::params::*; /// Assumes a to be standard representative. /// /// Returns a1. -pub fn power2round(a: i32, a0: &mut i32) -> i32 -{ +pub fn power2round(a: i32, a0: &mut i32) -> i32 { let a1 = (a + (1 << (D - 1)) - 1) >> D; *a0 = a - (a1 << D); return a1; @@ -19,8 +18,7 @@ pub fn power2round(a: i32, a0: &mut i32) -> i32 /// representative. /// /// Returns a1. -pub fn decompose(a0: &mut i32, a: i32) -> i32 -{ +pub fn decompose(a0: &mut i32, a: i32) -> i32 { let mut a1 = (a + 127) >> 7; if GAMMA2 == (Q - 1) / 32 { a1 = (a1 * 1025 + (1 << 21)) >> 22; @@ -38,8 +36,7 @@ pub fn decompose(a0: &mut i32, a: i32) -> i32 /// input element overflow into the high bits. /// /// Returns 1 if overflow. -pub fn make_hint(a0: i32, a1: i32) -> u8 -{ +pub fn make_hint(a0: i32, a1: i32) -> u8 { if a0 > GAMMA2_I32 || a0 < -GAMMA2_I32 || (a0 == -GAMMA2_I32 && a1 != 0) { return 1; } @@ -49,8 +46,7 @@ pub fn make_hint(a0: i32, a1: i32) -> u8 /// Correct high bits according to hint. /// /// Returns corrected high bits. -pub fn use_hint(a: i32, hint: u8) -> i32 -{ +pub fn use_hint(a: i32, hint: u8) -> i32 { let mut a0 = 0i32; let a1 = decompose(&mut a0, a); if hint == 0 { diff --git a/src/sign.rs b/src/sign.rs index efedcd4..6067211 100644 --- a/src/sign.rs +++ b/src/sign.rs @@ -7,8 +7,7 @@ pub fn crypto_sign_keypair( pk: &mut [u8], sk: &mut [u8], seed: Option<&[u8]>, -) -> u8 -{ +) -> u8 { let mut init_seed = [0u8; SEEDBYTES]; match seed { Some(x) => init_seed.copy_from_slice(x), @@ -65,8 +64,7 @@ pub fn crypto_sign_keypair( return 0; } -pub fn crypto_sign_signature(sig: &mut [u8], m: &[u8], sk: &[u8]) -{ +pub fn crypto_sign_signature(sig: &mut [u8], m: &[u8], sk: &[u8]) { // `key` and `mu` are concatenated let mut keymu = [0u8; SEEDBYTES + CRHBYTES]; @@ -178,8 +176,7 @@ pub fn crypto_sign_verify( sig: &[u8], m: &[u8], pk: &[u8], -) -> Result<(), SignError> -{ +) -> Result<(), SignError> { let mut buf = [0u8; K * POLYW1_PACKEDBYTES]; let mut rho = [0u8; SEEDBYTES]; let mut mu = [0u8; CRHBYTES]; diff --git a/src/symmetric.rs b/src/symmetric.rs index 2ce92c2..8593127 100644 --- a/src/symmetric.rs +++ b/src/symmetric.rs @@ -23,13 +23,11 @@ pub const STREAM256_BLOCKBYTES: usize = AES256CTR_BLOCKBYTES; #[cfg(not(feature = "aes"))] pub const STREAM256_BLOCKBYTES: usize = SHAKE256_RATE; -pub fn _crh(out: &mut [u8], input: &[u8], inbytes: usize) -{ +pub fn _crh(out: &mut [u8], input: &[u8], inbytes: usize) { shake256(out, CRHBYTES, input, inbytes) } -pub fn stream128_init(state: &mut Stream128State, seed: &[u8], nonce: u16) -{ +pub fn stream128_init(state: &mut Stream128State, seed: &[u8], nonce: u16) { #[cfg(not(feature = "aes"))] dilithium_shake128_stream_init(state, seed, nonce); @@ -41,8 +39,7 @@ pub fn stream128_squeezeblocks( out: &mut [u8], outblocks: u64, state: &mut Stream128State, -) -{ +) { #[cfg(not(feature = "aes"))] shake128_squeezeblocks(out, outblocks as usize, state); @@ -50,8 +47,7 @@ pub fn stream128_squeezeblocks( aes256ctr_squeezeblocks(out, outblocks, state); } -pub fn stream256_init(state: &mut Stream256State, seed: &[u8], nonce: u16) -{ +pub fn stream256_init(state: &mut Stream256State, seed: &[u8], nonce: u16) { #[cfg(not(feature = "aes"))] dilithium_shake256_stream_init(state, seed, nonce); @@ -63,8 +59,7 @@ pub fn stream256_squeezeblocks( out: &mut [u8], outblocks: u64, state: &mut Stream256State, -) -{ +) { #[cfg(not(feature = "aes"))] shake256_squeezeblocks(out, outblocks as usize, state); @@ -77,8 +72,7 @@ pub fn dilithium_aes256ctr_init( state: &mut Aes256ctrCtx, key: &[u8], nonce: u16, -) -{ +) { let mut expnonce = [0u8; 12]; expnonce[0] = nonce as u8; expnonce[1] = (nonce >> 8) as u8; @@ -90,8 +84,7 @@ pub fn dilithium_shake128_stream_init( state: &mut KeccakState, seed: &[u8], nonce: u16, -) -{ +) { let t = [nonce as u8, (nonce >> 8) as u8]; state.init(); shake128_absorb(state, seed, SEEDBYTES); @@ -104,8 +97,7 @@ pub fn dilithium_shake256_stream_init( state: &mut KeccakState, seed: &[u8], nonce: u16, -) -{ +) { let t = [nonce as u8, (nonce >> 8) as u8]; state.init(); shake256_absorb(state, seed, CRHBYTES); diff --git a/src/wasm.rs b/src/wasm.rs index b094e4a..123e49b 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -8,72 +8,68 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct Keys { - keypair: api::Keypair + keypair: api::Keypair, } #[wasm_bindgen] pub fn keypair() -> Keys { - Keys { - keypair: api::Keypair::generate() - } + Keys { + keypair: api::Keypair::generate(), + } } #[wasm_bindgen] impl Keys { - - #[wasm_bindgen(constructor)] - pub fn new() -> Keys { - keypair() - } - - #[wasm_bindgen(getter)] - pub fn pubkey(&self) -> Box<[u8]> { - Box::new(self.keypair.public) - } - - #[wasm_bindgen(getter)] - pub fn secret(&self) -> Box<[u8]> { - self.keypair.expose_secret().to_vec().into_boxed_slice() - } - - #[wasm_bindgen] - pub fn sign(&self,msg: Box<[u8]>)-> Box<[u8]> { - Box::new(self.keypair.sign(&msg)) - } - + #[wasm_bindgen(constructor)] + pub fn new() -> Keys { + keypair() + } + + #[wasm_bindgen(getter)] + pub fn pubkey(&self) -> Box<[u8]> { + Box::new(self.keypair.public) + } + + #[wasm_bindgen(getter)] + pub fn secret(&self) -> Box<[u8]> { + self.keypair.expose_secret().to_vec().into_boxed_slice() + } + + #[wasm_bindgen] + pub fn sign(&self, msg: Box<[u8]>) -> Box<[u8]> { + Box::new(self.keypair.sign(&msg)) + } } #[wasm_bindgen] pub fn verify(sig: Box<[u8]>, msg: Box<[u8]>, public_key: Box<[u8]>) -> bool { - api::verify(&sig, &msg, &public_key).is_ok() + api::verify(&sig, &msg, &public_key).is_ok() } - #[wasm_bindgen] pub struct Params { - #[wasm_bindgen(readonly)] - pub publicKeyBytes: usize, - #[wasm_bindgen(readonly)] - pub secretKeyBytes: usize, - #[wasm_bindgen(readonly)] - pub signBytes: usize, + #[wasm_bindgen(readonly)] + pub publicKeyBytes: usize, + #[wasm_bindgen(readonly)] + pub secretKeyBytes: usize, + #[wasm_bindgen(readonly)] + pub signBytes: usize, } #[wasm_bindgen] impl Params { - #[wasm_bindgen(getter)] - pub fn publicKeyBytes() -> usize { - PUBLICKEYBYTES - } - - #[wasm_bindgen(getter)] - pub fn secretKeyBytes() -> usize { - SECRETKEYBYTES - } - - #[wasm_bindgen(getter)] - pub fn signBytes() -> usize { - SIGNBYTES - } + #[wasm_bindgen(getter)] + pub fn publicKeyBytes() -> usize { + PUBLICKEYBYTES + } + + #[wasm_bindgen(getter)] + pub fn secretKeyBytes() -> usize { + SECRETKEYBYTES + } + + #[wasm_bindgen(getter)] + pub fn signBytes() -> usize { + SIGNBYTES + } } - diff --git a/tests/integration.rs b/tests/integration.rs index a7b2178..cd0dfd9 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -1,8 +1,7 @@ use pqc_dilithium::*; #[test] -fn sign_then_verify_valid() -{ +fn sign_then_verify_valid() { let msg = b"Hello"; let keys = Keypair::generate(); let signature = keys.sign(msg); @@ -10,8 +9,7 @@ fn sign_then_verify_valid() } #[test] -fn sign_then_verify_invalid() -{ +fn sign_then_verify_invalid() { let msg = b"Hello"; let keys = Keypair::generate(); let mut signature = keys.sign(msg); diff --git a/tests/kat.rs b/tests/kat.rs index 2007fd0..5300946 100644 --- a/tests/kat.rs +++ b/tests/kat.rs @@ -15,8 +15,7 @@ const MODE: u8 = if cfg!(feature = "mode2") { const AES: &str = if cfg!(feature = "aes") { "-AES" } else { "" }; #[test] -fn keypair() -{ +fn keypair() { let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let filename = format!("PQCsignKAT_Dilithium{}{}.rsp", MODE, AES); let katvec = kats(&mut path.clone(), &filename); @@ -33,8 +32,7 @@ fn keypair() } #[test] -pub fn sign() -{ +pub fn sign() { let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let filename = format!("PQCsignKAT_Dilithium{}{}.rsp", MODE, AES); let katvec = kats(&mut path, &filename); @@ -49,8 +47,7 @@ pub fn sign() } #[test] -pub fn verify() -{ +pub fn verify() { let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let filename = format!("PQCsignKAT_Dilithium{}{}.rsp", MODE, AES); let katvec = kats(&mut path, &filename); diff --git a/www/package.json b/www/package.json index d0b945f..761aa1c 100644 --- a/www/package.json +++ b/www/package.json @@ -12,7 +12,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/rustwasm/create-wasm-app.git" + "url": "git+https://github.com/Argyle-Software/dilithium.git" }, "keywords": [ "webassembly", @@ -23,9 +23,9 @@ "author": "Mitchell Berry ", "license": "(MIT OR Apache-2.0)", "bugs": { - "url": "https://github.com/rustwasm/create-wasm-app/issues" + "url": "https://github.com/Argyle-Software/dilithium/issues" }, - "homepage": "https://github.com/rustwasm/create-wasm-app#readme", + "homepage": "https://github.com/Argyle-Software/dilithium", "dependencies": { "pqc_dilithium": "file:../pkg" },