Function ring::ec::suite_b::ecdsa::digest_scalar::digest_scalar

source ·
pub fn digest_scalar(ops: &ScalarOps, msg: Digest) -> Elem<N, Unencoded>
Expand description

Calculate the digest of msg using the digest algorithm digest_alg. Then convert the digest to a scalar in the range [0, n) as described in NIST’s FIPS 186-4 Section 4.2. Note that this is one of the few cases where a Scalar is allowed to have the value zero.

NIST’s FIPS 186-4 4.2 says “When the length of the output of the hash function is greater than N (i.e., the bit length of q), then the leftmost N bits of the hash function output block shall be used in any calculation using the hash function output during the generation or verification of a digital signature.”

“Leftmost N bits” means “N most significant bits” because we interpret the digest as a bit-endian encoded integer.

The NSA guide instead vaguely suggests that we should convert the digest value to an integer and then reduce it mod n. However, real-world implementations (e.g. digest_to_bn in OpenSSL and hashToInt in Go) do what FIPS 186-4 says to do, not what the NSA guide suggests.

Why shifting the value right by at most one bit is sufficient: P-256’s n has its 256th bit set; i.e. 2255 < n < 2256. Once we’ve truncated the digest to 256 bits and converted it to an integer, it will have a value less than 2256. If the value is larger than n then shifting it one bit right will give a value less than 2255, which is less than n. The analogous argument applies for P-384. However, it does not apply in general; for example, it doesn’t apply to P-521.