nis1_crypto/
lib.rs

1// Copyright 2021 BlockPuppets developers.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9extern crate core_crypto as core;
10#[cfg(feature = "serde")]
11extern crate serde_crate as serde;
12
13use anyhow::{bail, Result};
14
15use crate::core::curve25519::scalar::Scalar;
16
17pub use self::cipher::*;
18pub use self::keypair::*;
19
20mod cipher;
21mod internal_private_key;
22mod internal_public_key;
23mod internal_signature;
24mod keccak_256;
25pub mod keypair;
26
27#[inline(always)]
28pub(crate) fn check_scalar(bytes: [u8; 32]) -> Result<Scalar> {
29    // Since this is only used in signature deserialisation (i.e. upon
30    // verification), we can do a "succeed fast" trick by checking that the most
31    // significant 4 bits are unset.  If they are unset, we can succeed fast
32    // because we are guaranteed that the scalar is fully reduced.  However, if
33    // the 4th most significant bit is set, we must do the full reduction check,
34    // as the order of the basepoint is roughly a 2^(252.5) bit number.
35    //
36    // This succeed-fast trick should succeed for roughly half of all scalars.
37    if bytes[31] & 240 == 0 {
38        return Ok(Scalar::from_bits(bytes));
39    }
40
41    match Scalar::from_canonical_bytes(bytes) {
42        None => bail!("ScalarFormatError"),
43        Some(x) => Ok(x),
44    }
45}