Update hash_to_field to correct a discrepancy with the Hashing to Elliptic Curves Internet Draft

pointed out in the NCC audit.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2021-03-27 13:45:11 +00:00
parent 0a6b2f6eb5
commit a1194672c5
3 changed files with 14 additions and 9 deletions

View file

@ -1,6 +1,7 @@
//! This module implements "simplified SWU" hashing to short Weierstrass curves
//! with a = 0.
use static_assertions::const_assert;
use subtle::ConstantTimeEq;
use crate::arithmetic::{CurveExt, FieldExt};
@ -18,6 +19,10 @@ pub fn hash_to_field<F: FieldExt>(
// Assume that the field size is 32 bytes and k is 256, where k is defined in
// <https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-10.html#name-security-considerations-3>.
const CHUNKLEN: usize = 64;
const_assert!(CHUNKLEN * 2 < 256);
// Input block size of BLAKE2b.
const R_IN_BYTES: usize = 128;
let personal = [0u8; 16];
let empty_hasher = blake2b_simd::Params::new()
@ -27,9 +32,9 @@ pub fn hash_to_field<F: FieldExt>(
let b_0 = empty_hasher
.clone()
.update(&[0; CHUNKLEN])
.update(&[0; R_IN_BYTES])
.update(message)
.update(&[0, 128, 0])
.update(&[0, (CHUNKLEN * 2) as u8, 0])
.update(domain_prefix.as_bytes())
.update(b"-")
.update(curve_id.as_bytes())

View file

@ -140,17 +140,17 @@ fn test_hash_to_curve() {
// This test vector is chosen so that the first map_to_curve_simple_swu takes the gx1 square
// "branch" and the second takes the gx1 non-square "branch" (opposite to the Vesta test vector).
let hash = Point::hash_to_curve("z.cash:test");
let p: Point = hash(b"world");
let p: Point = hash(b"Trans rights now!");
let (x, y, z) = p.jacobian_coordinates();
assert!(
format!("{:?}", x) == "0x2ae2d9bde5a5b4bc1f1e7154f18a407ac826c9d7cd23c3b33efa0f237e99cd35"
format!("{:?}", x) == "0x36a6e3a9c50b7b6540cb002c977c82f37f8a875fb51eb35327ee1452e6ce7947"
);
assert!(
format!("{:?}", y) == "0x3ca16b5bf2e6c41cdf781ead8ba61400becbc16430d026b65b707560b98f8b31"
format!("{:?}", y) == "0x01da3b4403d73252f2d7e9c19bc23dc6a080f2d02f8262fca4f7e3d756ac6a7c"
);
assert!(
format!("{:?}", z) == "0x2502d25cc3b1129d933af3ac34822111bfd070609fdebdfb778dd25cf40f9b82"
format!("{:?}", z) == "0x1d48103df8fcbb70d1809c1806c95651dd884a559fec0549658537ce9d94bed9"
);
assert!(bool::from(p.is_on_curve()));

View file

@ -59,12 +59,12 @@ fn test_hash_to_curve() {
let (x, y, z) = p.jacobian_coordinates();
assert!(
format!("{:?}", x) == "0x24c3431db13111fcba2f214a0662ae48e675801988c5705877525750b65f7ad8"
format!("{:?}", x) == "0x12763505036e0e1a6684b7a7d8d5afb7378cc2b191a95e34f44824a06fcbd08e"
);
assert!(
format!("{:?}", y) == "0x0df21621bf38070d79193ec5959fc2bb09468e71c0190d0217b0984fc92282f3"
format!("{:?}", y) == "0x0256eafc0188b79bfa7c4b2b393893ddc298e90da500fa4a9aee17c2ea4240e6"
);
assert!(
format!("{:?}", z) == "0x3e95ef9cbe5a9978c0d82635b242cf773ecfbc764ae9b936aba64c43f67091c6"
format!("{:?}", z) == "0x1b58d4aa4d68c3f4d9916b77c79ff9911597a27f2ee46244e98eb9615172d2ad"
);
}