Skip to content
Permalink
Browse files Browse the repository at this point in the history
Prevent side channel leak in Scala::check_overflow
  • Loading branch information
sorpaas committed Oct 3, 2019
1 parent 91d4b49 commit 11ba23a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
7 changes: 6 additions & 1 deletion Cargo.toml
Expand Up @@ -2,7 +2,7 @@
name = "libsecp256k1"
description = "Pure Rust secp256k1 implementation."
license = "Apache-2.0"
version = "0.3.0"
version = "0.4.0"
authors = ["Wei Tang <hi@that.world>"]
repository = "https://github.com/sorpaas/libsecp256k1-rs"
keywords = [ "crypto", "ECDSA", "secp256k1", "bitcoin", "no_std" ]
Expand All @@ -18,12 +18,17 @@ sha2 = "0.8"
digest = "0.8"
typenum = "1.11"
arrayref = "0.3"
subtle = { version = "2.2", default-features = false }

[dev-dependencies]
secp256k1-test = "0.7"
clear_on_drop = "0.2"
rand-test = { package = "rand", version = "0.4" }

[features]
default = ["std"]
std = ["subtle/std", "rand/std"]

[workspace]
members = [
"./gen/ecmult",
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Expand Up @@ -7,7 +7,7 @@
unused_variables, non_shorthand_field_patterns,
unreachable_code, unused_parens)]

#![no_std]
#![cfg_attr(not(feature = "std"), no_std)]

#[macro_use]
mod field;
Expand Down
31 changes: 16 additions & 15 deletions src/scalar.rs
@@ -1,4 +1,5 @@
use core::ops::{Add, AddAssign, Mul, MulAssign};
use subtle::Choice;

const SECP256K1_N_0: u32 = 0xD0364141;
const SECP256K1_N_1: u32 = 0xBFD25E8C;
Expand Down Expand Up @@ -69,21 +70,21 @@ impl Scalar {

#[must_use]
fn check_overflow(&self) -> bool {
let mut yes: bool = false;
let mut no: bool = false;
no = no || (self.0[7] < SECP256K1_N_7); /* No need for a > check. */
no = no || (self.0[6] < SECP256K1_N_6); /* No need for a > check. */
no = no || (self.0[5] < SECP256K1_N_5); /* No need for a > check. */
no = no || (self.0[4] < SECP256K1_N_4);
yes = yes || ((self.0[4] > SECP256K1_N_4) && !no);
no = no || ((self.0[3] < SECP256K1_N_3) && !yes);
yes = yes || ((self.0[3] > SECP256K1_N_3) && !no);
no = no || ((self.0[2] < SECP256K1_N_2) && !yes);
yes = yes || ((self.0[2] > SECP256K1_N_2) && !no);
no = no || ((self.0[1] < SECP256K1_N_1) && !yes);
yes = yes || ((self.0[1] > SECP256K1_N_1) && !no);
yes = yes || ((self.0[0] >= SECP256K1_N_0) && !no);
return yes;
let mut yes: Choice = 0.into();
let mut no: Choice = 0.into();
no |= Choice::from((self.0[7] < SECP256K1_N_7) as u8); /* No need for a > check. */
no |= Choice::from((self.0[6] < SECP256K1_N_6) as u8); /* No need for a > check. */
no |= Choice::from((self.0[5] < SECP256K1_N_5) as u8); /* No need for a > check. */
no |= Choice::from((self.0[4] < SECP256K1_N_4) as u8);
yes |= Choice::from((self.0[4] > SECP256K1_N_4) as u8) & !no;
no |= Choice::from((self.0[3] < SECP256K1_N_3) as u8) & !yes;
yes |= Choice::from((self.0[3] > SECP256K1_N_3) as u8) & !no;
no |= Choice::from((self.0[2] < SECP256K1_N_2) as u8) & !yes;
yes |= Choice::from((self.0[2] > SECP256K1_N_2) as u8) & !no;
no |= Choice::from((self.0[1] < SECP256K1_N_1) as u8) & !yes;
yes |= Choice::from((self.0[1] > SECP256K1_N_1) as u8) & !no;
yes |= Choice::from((self.0[0] >= SECP256K1_N_0) as u8) & !no;
return yes.into();
}

#[must_use]
Expand Down

0 comments on commit 11ba23a

Please sign in to comment.