Skip to content

Commit 2874b5a

Browse files
authoredJul 21, 2024··
Merge pull request #90 from andrewwhitehead/h2c-api-upd
Update to hash-to-curve draft 16, with some API adjustments
2 parents e457e51 + 09466e0 commit 2874b5a

12 files changed

+1297
-1237
lines changed
 

‎Cargo.lock

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ rustdoc-args = [ "--html-in-header", "katex-header.html" ]
1818
[dev-dependencies]
1919
csv = ">= 1.0, < 1.2" # csv 1.2 has MSRV 1.60
2020
criterion = "0.3"
21-
hex = "0.4"
21+
hex-literal = "0.3"
2222
rand_xorshift = "0.3"
2323
sha2 = "0.9"
2424
sha3 = "0.9"
@@ -69,7 +69,7 @@ bits = ["ff/bits"]
6969
groups = ["group"]
7070
pairings = ["groups", "pairing"]
7171
alloc = ["group/alloc"]
72-
experimental = ["digest"]
72+
experimental = ["digest", "groups"]
7373
nightly = ["subtle/nightly"]
7474

7575
[[test]]

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ If you want to propose "substantial" changes to this crate, please
2121
* `alloc` (on by default): Enables APIs that require an allocator; these include pairing optimizations.
2222
* `nightly`: Enables `subtle/nightly` which tries to prevent compiler optimizations that could jeopardize constant time operations. Requires the nightly Rust compiler.
2323
* `experimental`: Enables experimental features. These features have no backwards-compatibility guarantees and may change at any time; users that depend on specific behaviour should pin an exact version of this crate. The current list of experimental features:
24-
* Hashing to curves ([Internet Draft v12](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-12))
24+
* Hashing to curves ([Internet Draft v16](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16))
2525

2626
## [Documentation](https://docs.rs/bls12_381)
2727

‎benches/hash_to_curve.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn criterion_benchmark(c: &mut Criterion) {
2020
move |b| {
2121
b.iter(|| {
2222
<G1Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::encode_to_curve(
23-
black_box(message),
23+
[black_box(message)],
2424
black_box(dst),
2525
)
2626
})
@@ -29,7 +29,7 @@ fn criterion_benchmark(c: &mut Criterion) {
2929
c.bench_function(&format!("{} hash_to_curve SSWU SHA-256", name), move |b| {
3030
b.iter(|| {
3131
<G1Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::hash_to_curve(
32-
black_box(message),
32+
[black_box(message)],
3333
black_box(dst),
3434
)
3535
})
@@ -47,7 +47,7 @@ fn criterion_benchmark(c: &mut Criterion) {
4747
move |b| {
4848
b.iter(|| {
4949
<G2Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::encode_to_curve(
50-
black_box(message),
50+
[black_box(message)],
5151
black_box(dst),
5252
)
5353
})
@@ -56,7 +56,7 @@ fn criterion_benchmark(c: &mut Criterion) {
5656
c.bench_function(&format!("{} hash_to_curve SSWU SHA-256", name), move |b| {
5757
b.iter(|| {
5858
<G2Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::hash_to_curve(
59-
black_box(message),
59+
[black_box(message)],
6060
black_box(dst),
6161
)
6262
})

‎src/hash_to_curve/expand_msg.rs

+166-127
Large diffs are not rendered by default.

‎src/hash_to_curve/map_g1.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ use super::chain::chain_pm3div4;
66
use super::{HashToField, MapToCurve, Sgn0};
77
use crate::fp::Fp;
88
use crate::g1::G1Projective;
9-
use crate::generic_array::{typenum::U64, GenericArray};
9+
use crate::generic_array::{
10+
typenum::{U32, U64},
11+
GenericArray,
12+
};
1013

1114
/// Coefficients of the 11-isogeny x map's numerator
1215
const ISO11_XNUM: [Fp; 12] = [
@@ -504,6 +507,9 @@ impl HashToField for Fp {
504507
// ceil(log2(p)) = 381, m = 1, k = 128.
505508
type InputLength = U64;
506509

510+
// k = 128
511+
type XofOutputLength = U32;
512+
507513
fn from_okm(okm: &GenericArray<u8, U64>) -> Fp {
508514
const F_2_256: Fp = Fp::from_raw_unchecked([
509515
0x075b_3cd7_c5ce_820f,
@@ -538,9 +544,9 @@ impl Sgn0 for Fp {
538544

539545
/// Maps an element of [`Fp`] to a point on iso-G1.
540546
///
541-
/// Implements [section 6.6.2 of `draft-irtf-cfrg-hash-to-curve-12`][sswu].
547+
/// Implements [section 6.6.2 of `draft-irtf-cfrg-hash-to-curve-16`][sswu].
542548
///
543-
/// [sswu]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-12#section-6.6.2
549+
/// [sswu]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-6.6.2
544550
fn map_to_curve_simple_swu(u: &Fp) -> G1Projective {
545551
let usq = u.square();
546552
let xi_usq = SSWU_XI * usq;

‎src/hash_to_curve/map_g2.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTi
55
use super::chain::chain_p2m9div16;
66
use super::{HashToField, MapToCurve, Sgn0};
77
use crate::generic_array::{
8-
typenum::{U128, U64},
8+
typenum::{U128, U32, U64},
99
GenericArray,
1010
};
1111
use crate::{fp::Fp, fp2::Fp2, g2::G2Projective};
@@ -368,6 +368,9 @@ impl HashToField for Fp2 {
368368
// ceil(log2(p)) = 381, m = 2, k = 128.
369369
type InputLength = U128;
370370

371+
// k = 128
372+
type XofOutputLength = U32;
373+
371374
fn from_okm(okm: &GenericArray<u8, U128>) -> Fp2 {
372375
let c0 = <Fp as HashToField>::from_okm(GenericArray::<u8, U64>::from_slice(&okm[..64]));
373376
let c1 = <Fp as HashToField>::from_okm(GenericArray::<u8, U64>::from_slice(&okm[64..]));

‎src/hash_to_curve/map_scalar.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
//! Implementation of hash-to-field for Scalar values
22
33
use super::HashToField;
4-
use crate::generic_array::{typenum::U48, GenericArray};
4+
use crate::generic_array::{
5+
typenum::{U32, U48},
6+
GenericArray,
7+
};
58
use crate::scalar::Scalar;
69

710
impl HashToField for Scalar {
811
// ceil(log2(p)) = 255, m = 1, k = 128.
912
type InputLength = U48;
1013

14+
// k = 128
15+
type XofOutputLength = U32;
16+
1117
fn from_okm(okm: &GenericArray<u8, U48>) -> Scalar {
1218
let mut bs = [0u8; 64];
1319
bs[16..].copy_from_slice(okm);

‎src/hash_to_curve/mod.rs

+28-17
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,22 @@ use subtle::Choice;
88
pub(crate) mod chain;
99

1010
mod expand_msg;
11-
pub use self::expand_msg::{
12-
ExpandMessage, ExpandMessageState, ExpandMsgXmd, ExpandMsgXof, InitExpandMessage,
13-
};
11+
pub use self::expand_msg::{ExpandMessage, ExpandMsgXmd, ExpandMsgXof, Message};
1412

1513
mod map_g1;
1614
mod map_g2;
1715
mod map_scalar;
1816

19-
use crate::generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
17+
use crate::generic_array::{
18+
typenum::{IsLess, Unsigned, U256},
19+
ArrayLength, GenericArray,
20+
};
2021

2122
/// Enables a byte string to be hashed into one or more field elements for a given curve.
2223
///
23-
/// Implements [section 5 of `draft-irtf-cfrg-hash-to-curve-12`][hash_to_field].
24+
/// Implements [section 5 of `draft-irtf-cfrg-hash-to-curve-16`][hash_to_field].
2425
///
25-
/// [hash_to_field]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-12#section-5
26+
/// [hash_to_field]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-5
2627
pub trait HashToField: Sized {
2728
/// The length of the data used to produce an individual field element.
2829
///
@@ -31,20 +32,30 @@ pub trait HashToField: Sized {
3132
/// security parameter.
3233
type InputLength: ArrayLength<u8>;
3334

35+
/// The number of bytes to read from the extensible output hash function.
36+
///
37+
/// This must be set to `ceil(2 * k / 8)`, where `k` is the security parameter. This
38+
/// is used when handling DST values longer than 255 bytes.
39+
type XofOutputLength: ArrayLength<u8> + IsLess<U256>;
40+
3441
/// Interprets the given output keying material as a big endian integer, and reduces
3542
/// it into a field element.
3643
fn from_okm(okm: &GenericArray<u8, Self::InputLength>) -> Self;
3744

3845
/// Hashes a byte string of arbitrary length into one or more elements of `Self`,
3946
/// using [`ExpandMessage`] variant `X`.
4047
///
41-
/// Implements [section 5.3 of `draft-irtf-cfrg-hash-to-curve-12`][hash_to_field].
48+
/// Implements [section 5.2 of `draft-irtf-cfrg-hash-to-curve-16`][hash_to_field].
4249
///
43-
/// [hash_to_field]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-12#section-5.3
44-
fn hash_to_field<X: ExpandMessage>(message: &[u8], dst: &[u8], output: &mut [Self]) {
50+
/// [hash_to_field]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-5.2
51+
fn hash_to_field<X, M>(message: M, dst: &[u8], output: &mut [Self])
52+
where
53+
X: ExpandMessage,
54+
M: Message,
55+
{
4556
let len_per_elm = Self::InputLength::to_usize();
4657
let len_in_bytes = output.len() * len_per_elm;
47-
let mut expander = X::init_expand(message, dst, len_in_bytes);
58+
let mut expander = X::init_expand::<M, Self::XofOutputLength>(message, dst, len_in_bytes);
4859

4960
let mut buf = GenericArray::<u8, Self::InputLength>::default();
5061
output.iter_mut().for_each(|item| {
@@ -72,9 +83,9 @@ pub trait HashToCurve<X: ExpandMessage>: MapToCurve + for<'a> Add<&'a Self, Outp
7283
///
7384
/// This function is suitable for most applications requiring a random
7485
/// oracle returning points in `Self`.
75-
fn hash_to_curve(message: impl AsRef<[u8]>, dst: &[u8]) -> Self {
86+
fn hash_to_curve<M: Message>(message: M, dst: &[u8]) -> Self {
7687
let mut u = [Self::Field::default(); 2];
77-
Self::Field::hash_to_field::<X>(message.as_ref(), dst, &mut u);
88+
Self::Field::hash_to_field::<X, M>(message, dst, &mut u);
7889
let p1 = Self::map_to_curve(&u[0]);
7990
let p2 = Self::map_to_curve(&u[1]);
8091
(p1 + &p2).clear_h()
@@ -85,13 +96,13 @@ pub trait HashToCurve<X: ExpandMessage>: MapToCurve + for<'a> Add<&'a Self, Outp
8596
/// The distribution of its output is not uniformly random in `Self`: the set of
8697
/// possible outputs of this function is only a fraction of the points in `Self`, and
8798
/// some elements of this set are more likely to be output than others. See
88-
/// [section 10.1 of `draft-irtf-cfrg-hash-to-curve-12`][encode_to_curve-distribution]
99+
/// [section 10.4 of `draft-irtf-cfrg-hash-to-curve-16`][encode_to_curve-distribution]
89100
/// for a more precise definition of `encode_to_curve`'s output distribution.
90101
///
91-
/// [encode_to_curve-distribution]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-12#section-10.1
92-
fn encode_to_curve(message: impl AsRef<[u8]>, dst: &[u8]) -> Self {
102+
/// [encode_to_curve-distribution]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-10.4
103+
fn encode_to_curve<M: Message>(message: M, dst: &[u8]) -> Self {
93104
let mut u = [Self::Field::default(); 1];
94-
Self::Field::hash_to_field::<X>(message.as_ref(), dst, &mut u);
105+
Self::Field::hash_to_field::<X, M>(message, dst, &mut u);
95106
let p = Self::map_to_curve(&u[0]);
96107
p.clear_h()
97108
}
@@ -107,7 +118,7 @@ where
107118
pub(crate) trait Sgn0 {
108119
/// Returns either 0 or 1 indicating the "sign" of x, where sgn0(x) == 1
109120
/// just when x is "negative". (In other words, this function always considers 0 to be positive.)
110-
/// <https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-4.1>
121+
/// <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-4.1>
111122
/// The equivalent for draft 6 would be `lexicographically_largest`.
112123
fn sgn0(&self) -> Choice;
113124
}

‎tests/expand_msg.rs

+866-882
Large diffs are not rendered by default.

‎tests/hash_to_curve_g1.rs

+92-87
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,70 @@
1-
use bls12_381::G1Projective;
1+
use bls12_381::{
2+
hash_to_curve::{ExpandMsgXmd, HashToCurve},
3+
G1Affine, G1Projective,
4+
};
5+
use hex_literal::hex;
6+
use sha2::Sha256;
27

3-
// test vectors from the draft 10 RFC
4-
#[test]
5-
fn test_encode_to_curve_10() {
6-
use bls12_381::{
7-
hash_to_curve::{ExpandMsgXmd, HashToCurve},
8-
G1Affine,
9-
};
10-
use std::string::{String, ToString};
8+
struct TestCase {
9+
msg: &'static [u8],
10+
dst: &'static [u8],
11+
expected: &'static [u8],
12+
}
1113

12-
struct TestCase {
13-
msg: &'static [u8],
14-
expected: [&'static str; 2],
15-
}
16-
impl TestCase {
17-
fn expected(&self) -> String {
18-
self.expected[0].to_string() + self.expected[1]
14+
impl TestCase {
15+
pub fn check_output(&self, output: &[u8]) {
16+
if output != self.expected {
17+
panic!(
18+
"Test vector result mismatch.\n\
19+
Message: {:x?}\n\
20+
DST: {:x?}\n\
21+
Expected: {:x?}\n\
22+
Found: {:x?}",
23+
self.msg, self.dst, self.expected, output
24+
)
1925
}
2026
}
27+
}
2128

22-
const DOMAIN: &[u8] = b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_NU_";
29+
// From <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#appendix-J.9.2>
30+
#[test]
31+
fn encode_to_curve_works_for_draft16_testvectors_g1_sha256_nu() {
32+
let dst = b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_NU_";
2333

2434
let cases = vec![
2535
TestCase {
2636
msg: b"",
27-
expected: [
28-
"184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba",
29-
"04407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3",
30-
],
37+
dst,
38+
expected: &hex!(
39+
"184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba
40+
04407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3"
41+
),
3142
},
3243
TestCase {
3344
msg: b"abc",
34-
expected: [
35-
"009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d",
36-
"1532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c",
37-
],
45+
dst,
46+
expected: &hex!(
47+
"009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d
48+
1532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c"
49+
),
3850
},
3951
TestCase {
4052
msg: b"abcdef0123456789",
41-
expected: [
42-
"1974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a",
43-
"15f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a3",
44-
]
53+
dst,
54+
expected: &hex!(
55+
"1974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a
56+
15f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a3"
57+
),
4558
},
4659
TestCase {
4760
msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
4861
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
4962
qqqqqqqqqqqqqqqqqqqqqqqqq",
50-
expected: [
51-
"0a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c",
52-
"1383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9",
53-
]
63+
dst,
64+
expected: &hex!(
65+
"0a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c
66+
1383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9"
67+
),
5468
},
5569
TestCase {
5670
msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
@@ -63,75 +77,64 @@ fn test_encode_to_curve_10() {
6377
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
6478
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
6579
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
66-
expected: [
67-
"0e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11",
68-
"0ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db",
69-
]
70-
}
80+
dst,
81+
expected: &hex!(
82+
"0e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11
83+
0ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db"
84+
),
85+
},
7186
];
7287

7388
for case in cases {
74-
let g = <G1Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::encode_to_curve(
75-
&case.msg, DOMAIN,
89+
let g = <G1Projective as HashToCurve<ExpandMsgXmd<Sha256>>>::encode_to_curve(
90+
[case.msg],
91+
case.dst,
7692
);
7793
let aff = G1Affine::from(g);
7894
let g_uncompressed = aff.to_uncompressed();
79-
80-
assert_eq!(case.expected(), hex::encode(&g_uncompressed[..]));
95+
case.check_output(&g_uncompressed);
8196
}
8297
}
8398

84-
// test vectors from the draft 10 RFC
99+
// From <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#appendix-J.9.1>
85100
#[test]
86-
fn test_hash_to_curve_10() {
87-
use bls12_381::{
88-
hash_to_curve::{ExpandMsgXmd, HashToCurve},
89-
G1Affine,
90-
};
91-
use std::string::{String, ToString};
92-
93-
struct TestCase {
94-
msg: &'static [u8],
95-
expected: [&'static str; 2],
96-
}
97-
impl TestCase {
98-
fn expected(&self) -> String {
99-
self.expected[0].to_string() + self.expected[1]
100-
}
101-
}
102-
103-
const DOMAIN: &[u8] = b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_";
101+
fn hash_to_curve_works_for_draft16_testvectors_g1_sha256_ro() {
102+
let dst = b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_";
104103

105104
let cases = vec![
106105
TestCase {
107106
msg: b"",
108-
expected: [
109-
"052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a1",
110-
"08ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265",
111-
],
107+
dst,
108+
expected: &hex!(
109+
"052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a1
110+
08ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265"
111+
),
112112
},
113113
TestCase {
114114
msg: b"abc",
115-
expected: [
116-
"03567bc5ef9c690c2ab2ecdf6a96ef1c139cc0b2f284dca0a9a7943388a49a3aee664ba5379a7655d3c68900be2f6903",
117-
"0b9c15f3fe6e5cf4211f346271d7b01c8f3b28be689c8429c85b67af215533311f0b8dfaaa154fa6b88176c229f2885d"
118-
],
115+
dst,
116+
expected: &hex!(
117+
"03567bc5ef9c690c2ab2ecdf6a96ef1c139cc0b2f284dca0a9a7943388a49a3aee664ba5379a7655d3c68900be2f6903
118+
0b9c15f3fe6e5cf4211f346271d7b01c8f3b28be689c8429c85b67af215533311f0b8dfaaa154fa6b88176c229f2885d"
119+
),
119120
},
120121
TestCase {
121122
msg: b"abcdef0123456789",
122-
expected: [
123-
"11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d98",
124-
"03a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709"
125-
]
123+
dst,
124+
expected: &hex!(
125+
"11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d98
126+
03a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709"
127+
),
126128
},
127129
TestCase {
128130
msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
129131
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
130132
qqqqqqqqqqqqqqqqqqqqqqqqq",
131-
expected: [
132-
"15f68eaa693b95ccb85215dc65fa81038d69629f70aeee0d0f677cf22285e7bf58d7cb86eefe8f2e9bc3f8cb84fac488",
133-
"1807a1d50c29f430b8cafc4f8638dfeeadf51211e1602a5f184443076715f91bb90a48ba1e370edce6ae1062f5e6dd38"
134-
]
133+
dst,
134+
expected: &hex!(
135+
"15f68eaa693b95ccb85215dc65fa81038d69629f70aeee0d0f677cf22285e7bf58d7cb86eefe8f2e9bc3f8cb84fac488
136+
1807a1d50c29f430b8cafc4f8638dfeeadf51211e1602a5f184443076715f91bb90a48ba1e370edce6ae1062f5e6dd38"
137+
),
135138
},
136139
TestCase {
137140
msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
@@ -144,19 +147,21 @@ fn test_hash_to_curve_10() {
144147
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
145148
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
146149
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
147-
expected: [
148-
"082aabae8b7dedb0e78aeb619ad3bfd9277a2f77ba7fad20ef6aabdc6c31d19ba5a6d12283553294c1825c4b3ca2dcfe",
149-
"05b84ae5a942248eea39e1d91030458c40153f3b654ab7872d779ad1e942856a20c438e8d99bc8abfbf74729ce1f7ac8"
150-
]
151-
}
150+
dst,
151+
expected: &hex!(
152+
"082aabae8b7dedb0e78aeb619ad3bfd9277a2f77ba7fad20ef6aabdc6c31d19ba5a6d12283553294c1825c4b3ca2dcfe
153+
05b84ae5a942248eea39e1d91030458c40153f3b654ab7872d779ad1e942856a20c438e8d99bc8abfbf74729ce1f7ac8"
154+
),
155+
},
152156
];
153157

154158
for case in cases {
155-
let g = <G1Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::hash_to_curve(
156-
&case.msg, DOMAIN,
159+
let g = <G1Projective as HashToCurve<ExpandMsgXmd<Sha256>>>::hash_to_curve(
160+
[case.msg],
161+
case.dst,
157162
);
158-
let g_uncompressed = G1Affine::from(g).to_uncompressed();
159-
160-
assert_eq!(case.expected(), hex::encode(&g_uncompressed[..]));
163+
let aff = G1Affine::from(g);
164+
let g_uncompressed = aff.to_uncompressed();
165+
case.check_output(&g_uncompressed);
161166
}
162167
}

‎tests/hash_to_curve_g2.rs

+114-108
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,78 @@
1-
use bls12_381::G2Projective;
1+
use bls12_381::{
2+
hash_to_curve::{ExpandMsgXmd, HashToCurve},
3+
G2Affine, G2Projective,
4+
};
5+
use hex_literal::hex;
6+
use sha2::Sha256;
27

3-
// test vectors from the draft 10 RFC
4-
#[test]
5-
fn test_encode_to_curve_10() {
6-
use bls12_381::{
7-
hash_to_curve::{ExpandMsgXmd, HashToCurve},
8-
G2Affine,
9-
};
10-
use std::string::{String, ToString};
8+
struct TestCase {
9+
msg: &'static [u8],
10+
dst: &'static [u8],
11+
expected: &'static [u8],
12+
}
1113

12-
struct TestCase {
13-
msg: &'static [u8],
14-
expected: [&'static str; 4],
15-
}
16-
impl TestCase {
17-
fn expected(&self) -> String {
18-
self.expected[0].to_string() + self.expected[1] + self.expected[2] + self.expected[3]
14+
impl TestCase {
15+
pub fn check_output(&self, output: &[u8]) {
16+
if output != self.expected {
17+
panic!(
18+
"Test vector result mismatch.\n\
19+
Message: {:x?}\n\
20+
DST: {:x?}\n\
21+
Expected: {:x?}\n\
22+
Found: {:x?}",
23+
self.msg, self.dst, self.expected, output
24+
)
1925
}
2026
}
27+
}
2128

22-
const DOMAIN: &[u8] = b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_NU_";
29+
// From <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#appendix-J.10.2>
30+
#[test]
31+
fn encode_to_curve_works_for_draft16_testvectors_g2_sha256_nu() {
32+
let dst = b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_NU_";
2333

2434
let cases = vec![
2535
TestCase {
2636
msg: b"",
27-
expected: [
28-
"126b855e9e69b1f691f816e48ac6977664d24d99f8724868a184186469ddfd4617367e94527d4b74fc86413483afb35b",
29-
"00e7f4568a82b4b7dc1f14c6aaa055edf51502319c723c4dc2688c7fe5944c213f510328082396515734b6612c4e7bb7",
30-
"1498aadcf7ae2b345243e281ae076df6de84455d766ab6fcdaad71fab60abb2e8b980a440043cd305db09d283c895e3d",
31-
"0caead0fd7b6176c01436833c79d305c78be307da5f6af6c133c47311def6ff1e0babf57a0fb5539fce7ee12407b0a42",
32-
],
37+
dst,
38+
expected: &hex!(
39+
"126b855e9e69b1f691f816e48ac6977664d24d99f8724868a184186469ddfd4617367e94527d4b74fc86413483afb35b
40+
00e7f4568a82b4b7dc1f14c6aaa055edf51502319c723c4dc2688c7fe5944c213f510328082396515734b6612c4e7bb7
41+
1498aadcf7ae2b345243e281ae076df6de84455d766ab6fcdaad71fab60abb2e8b980a440043cd305db09d283c895e3d
42+
0caead0fd7b6176c01436833c79d305c78be307da5f6af6c133c47311def6ff1e0babf57a0fb5539fce7ee12407b0a42"
43+
),
3344
},
3445
TestCase {
3546
msg: b"abc",
36-
expected: [
37-
"0296238ea82c6d4adb3c838ee3cb2346049c90b96d602d7bb1b469b905c9228be25c627bffee872def773d5b2a2eb57d",
38-
"108ed59fd9fae381abfd1d6bce2fd2fa220990f0f837fa30e0f27914ed6e1454db0d1ee957b219f61da6ff8be0d6441f",
39-
"153606c417e59fb331b7ae6bce4fbf7c5190c33ce9402b5ebe2b70e44fca614f3f1382a3625ed5493843d0b0a652fc3f",
40-
"033f90f6057aadacae7963b0a0b379dd46750c1c94a6357c99b65f63b79e321ff50fe3053330911c56b6ceea08fee656",
41-
],
47+
dst,
48+
expected: &hex!(
49+
"0296238ea82c6d4adb3c838ee3cb2346049c90b96d602d7bb1b469b905c9228be25c627bffee872def773d5b2a2eb57d
50+
108ed59fd9fae381abfd1d6bce2fd2fa220990f0f837fa30e0f27914ed6e1454db0d1ee957b219f61da6ff8be0d6441f
51+
153606c417e59fb331b7ae6bce4fbf7c5190c33ce9402b5ebe2b70e44fca614f3f1382a3625ed5493843d0b0a652fc3f
52+
033f90f6057aadacae7963b0a0b379dd46750c1c94a6357c99b65f63b79e321ff50fe3053330911c56b6ceea08fee656"
53+
),
4254
},
4355
TestCase {
4456
msg: b"abcdef0123456789",
45-
expected: [
46-
"0da75be60fb6aa0e9e3143e40c42796edf15685cafe0279afd2a67c3dff1c82341f17effd402e4f1af240ea90f4b659b",
47-
"038af300ef34c7759a6caaa4e69363cafeed218a1f207e93b2c70d91a1263d375d6730bd6b6509dcac3ba5b567e85bf3",
48-
"0492f4fed741b073e5a82580f7c663f9b79e036b70ab3e51162359cec4e77c78086fe879b65ca7a47d34374c8315ac5e",
49-
"19b148cbdf163cf0894f29660d2e7bfb2b68e37d54cc83fd4e6e62c020eaa48709302ef8e746736c0e19342cc1ce3df4",
50-
]
57+
dst,
58+
expected: &hex!(
59+
"0da75be60fb6aa0e9e3143e40c42796edf15685cafe0279afd2a67c3dff1c82341f17effd402e4f1af240ea90f4b659b
60+
038af300ef34c7759a6caaa4e69363cafeed218a1f207e93b2c70d91a1263d375d6730bd6b6509dcac3ba5b567e85bf3
61+
0492f4fed741b073e5a82580f7c663f9b79e036b70ab3e51162359cec4e77c78086fe879b65ca7a47d34374c8315ac5e
62+
19b148cbdf163cf0894f29660d2e7bfb2b68e37d54cc83fd4e6e62c020eaa48709302ef8e746736c0e19342cc1ce3df4"
63+
),
5164
},
5265
TestCase {
5366
msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
5467
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
5568
qqqqqqqqqqqqqqqqqqqqqqqqq",
56-
expected: [
57-
"12c8c05c1d5fc7bfa847f4d7d81e294e66b9a78bc9953990c358945e1f042eedafce608b67fdd3ab0cb2e6e263b9b1ad",
58-
"0c5ae723be00e6c3f0efe184fdc0702b64588fe77dda152ab13099a3bacd3876767fa7bbad6d6fd90b3642e902b208f9",
59-
"11c624c56dbe154d759d021eec60fab3d8b852395a89de497e48504366feedd4662d023af447d66926a28076813dd646",
60-
"04e77ddb3ede41b5ec4396b7421dd916efc68a358a0d7425bddd253547f2fb4830522358491827265dfc5bcc1928a569",
61-
]
69+
dst,
70+
expected: &hex!(
71+
"12c8c05c1d5fc7bfa847f4d7d81e294e66b9a78bc9953990c358945e1f042eedafce608b67fdd3ab0cb2e6e263b9b1ad
72+
0c5ae723be00e6c3f0efe184fdc0702b64588fe77dda152ab13099a3bacd3876767fa7bbad6d6fd90b3642e902b208f9
73+
11c624c56dbe154d759d021eec60fab3d8b852395a89de497e48504366feedd4662d023af447d66926a28076813dd646
74+
04e77ddb3ede41b5ec4396b7421dd916efc68a358a0d7425bddd253547f2fb4830522358491827265dfc5bcc1928a569"
75+
),
6276
},
6377
TestCase {
6478
msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
@@ -71,84 +85,74 @@ fn test_encode_to_curve_10() {
7185
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
7286
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
7387
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
74-
expected: [
75-
"1565c2f625032d232f13121d3cfb476f45275c303a037faa255f9da62000c2c864ea881e2bcddd111edc4a3c0da3e88d",
76-
"0ea4e7c33d43e17cc516a72f76437c4bf81d8f4eac69ac355d3bf9b71b8138d55dc10fd458be115afa798b55dac34be1",
77-
"0f8991d2a1ad662e7b6f58ab787947f1fa607fce12dde171bc17903b012091b657e15333e11701edcf5b63ba2a561247",
78-
"043b6f5fe4e52c839148dc66f2b3751e69a0f6ebb3d056d6465d50d4108543ecd956e10fa1640dfd9bc0030cc2558d28",
79-
]
80-
}
88+
dst,
89+
expected: &hex!(
90+
"1565c2f625032d232f13121d3cfb476f45275c303a037faa255f9da62000c2c864ea881e2bcddd111edc4a3c0da3e88d
91+
0ea4e7c33d43e17cc516a72f76437c4bf81d8f4eac69ac355d3bf9b71b8138d55dc10fd458be115afa798b55dac34be1
92+
0f8991d2a1ad662e7b6f58ab787947f1fa607fce12dde171bc17903b012091b657e15333e11701edcf5b63ba2a561247
93+
043b6f5fe4e52c839148dc66f2b3751e69a0f6ebb3d056d6465d50d4108543ecd956e10fa1640dfd9bc0030cc2558d28"
94+
),
95+
},
8196
];
8297

8398
for case in cases {
84-
let g = <G2Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::encode_to_curve(
85-
&case.msg, DOMAIN,
99+
let g = <G2Projective as HashToCurve<ExpandMsgXmd<Sha256>>>::encode_to_curve(
100+
[case.msg],
101+
case.dst,
86102
);
87-
let g_uncompressed = G2Affine::from(g).to_uncompressed();
88-
89-
assert_eq!(case.expected(), hex::encode(&g_uncompressed[..]));
103+
let aff = G2Affine::from(g);
104+
let g_uncompressed = aff.to_uncompressed();
105+
case.check_output(&g_uncompressed);
90106
}
91107
}
92108

93-
// test vectors from the draft 10 RFC
109+
// From <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#appendix-J.10.1>
94110
#[test]
95-
fn test_hash_to_curve_10() {
96-
use bls12_381::{
97-
hash_to_curve::{ExpandMsgXmd, HashToCurve},
98-
G2Affine,
99-
};
100-
use std::string::{String, ToString};
101-
102-
struct TestCase {
103-
msg: &'static [u8],
104-
expected: [&'static str; 4],
105-
}
106-
impl TestCase {
107-
fn expected(&self) -> String {
108-
self.expected[0].to_string() + self.expected[1] + self.expected[2] + self.expected[3]
109-
}
110-
}
111-
112-
const DOMAIN: &[u8] = b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_";
111+
fn hash_to_curve_works_for_draft16_testvectors_g2_sha256_ro() {
112+
let dst = b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_";
113113

114114
let cases = vec![
115115
TestCase {
116116
msg: b"",
117-
expected: [
118-
"05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d",
119-
"0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a",
120-
"12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d6",
121-
"0503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92",
122-
],
117+
dst,
118+
expected: &hex!(
119+
"05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d
120+
0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a
121+
12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d6
122+
0503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92"
123+
),
123124
},
124125
TestCase {
125126
msg: b"abc",
126-
expected: [
127-
"139cddbccdc5e91b9623efd38c49f81a6f83f175e80b06fc374de9eb4b41dfe4ca3a230ed250fbe3a2acf73a41177fd8",
128-
"02c2d18e033b960562aae3cab37a27ce00d80ccd5ba4b7fe0e7a210245129dbec7780ccc7954725f4168aff2787776e6",
129-
"00aa65dae3c8d732d10ecd2c50f8a1baf3001578f71c694e03866e9f3d49ac1e1ce70dd94a733534f106d4cec0eddd16",
130-
"1787327b68159716a37440985269cf584bcb1e621d3a7202be6ea05c4cfe244aeb197642555a0645fb87bf7466b2ba48",
131-
],
127+
dst,
128+
expected: &hex!(
129+
"139cddbccdc5e91b9623efd38c49f81a6f83f175e80b06fc374de9eb4b41dfe4ca3a230ed250fbe3a2acf73a41177fd8
130+
02c2d18e033b960562aae3cab37a27ce00d80ccd5ba4b7fe0e7a210245129dbec7780ccc7954725f4168aff2787776e6
131+
00aa65dae3c8d732d10ecd2c50f8a1baf3001578f71c694e03866e9f3d49ac1e1ce70dd94a733534f106d4cec0eddd16
132+
1787327b68159716a37440985269cf584bcb1e621d3a7202be6ea05c4cfe244aeb197642555a0645fb87bf7466b2ba48"
133+
),
132134
},
133135
TestCase {
134136
msg: b"abcdef0123456789",
135-
expected: [
136-
"190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c",
137-
"121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd0",
138-
"0bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be",
139-
"05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8",
140-
]
137+
dst,
138+
expected: &hex!(
139+
"190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c
140+
121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd0
141+
0bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be
142+
05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8"
143+
),
141144
},
142145
TestCase {
143146
msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
144147
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
145148
qqqqqqqqqqqqqqqqqqqqqqqqq",
146-
expected: [
147-
"0934aba516a52d8ae479939a91998299c76d39cc0c035cd18813bec433f587e2d7a4fef038260eef0cef4d02aae3eb91",
148-
"19a84dd7248a1066f737cc34502ee5555bd3c19f2ecdb3c7d9e24dc65d4e25e50d83f0f77105e955d78f4762d33c17da",
149-
"09bcccfa036b4847c9950780733633f13619994394c23ff0b32fa6b795844f4a0673e20282d07bc69641cee04f5e5662",
150-
"14f81cd421617428bc3b9fe25afbb751d934a00493524bc4e065635b0555084dd54679df1536101b2c979c0152d09192",
151-
]
149+
dst,
150+
expected: &hex!(
151+
"0934aba516a52d8ae479939a91998299c76d39cc0c035cd18813bec433f587e2d7a4fef038260eef0cef4d02aae3eb91
152+
19a84dd7248a1066f737cc34502ee5555bd3c19f2ecdb3c7d9e24dc65d4e25e50d83f0f77105e955d78f4762d33c17da
153+
09bcccfa036b4847c9950780733633f13619994394c23ff0b32fa6b795844f4a0673e20282d07bc69641cee04f5e5662
154+
14f81cd421617428bc3b9fe25afbb751d934a00493524bc4e065635b0555084dd54679df1536101b2c979c0152d09192"
155+
),
152156
},
153157
TestCase {
154158
msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
@@ -161,21 +165,23 @@ fn test_hash_to_curve_10() {
161165
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
162166
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
163167
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
164-
expected: [
165-
"11fca2ff525572795a801eed17eb12785887c7b63fb77a42be46ce4a34131d71f7a73e95fee3f812aea3de78b4d01569",
166-
"01a6ba2f9a11fa5598b2d8ace0fbe0a0eacb65deceb476fbbcb64fd24557c2f4b18ecfc5663e54ae16a84f5ab7f62534",
167-
"03a47f8e6d1763ba0cad63d6114c0accbef65707825a511b251a660a9b3994249ae4e63fac38b23da0c398689ee2ab52",
168-
"0b6798718c8aed24bc19cb27f866f1c9effcdbf92397ad6448b5c9db90d2b9da6cbabf48adc1adf59a1a28344e79d57e",
169-
]
170-
}
168+
dst,
169+
expected: &hex!(
170+
"11fca2ff525572795a801eed17eb12785887c7b63fb77a42be46ce4a34131d71f7a73e95fee3f812aea3de78b4d01569
171+
01a6ba2f9a11fa5598b2d8ace0fbe0a0eacb65deceb476fbbcb64fd24557c2f4b18ecfc5663e54ae16a84f5ab7f62534
172+
03a47f8e6d1763ba0cad63d6114c0accbef65707825a511b251a660a9b3994249ae4e63fac38b23da0c398689ee2ab52
173+
0b6798718c8aed24bc19cb27f866f1c9effcdbf92397ad6448b5c9db90d2b9da6cbabf48adc1adf59a1a28344e79d57e"
174+
),
175+
},
171176
];
172177

173178
for case in cases {
174-
let g = <G2Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::hash_to_curve(
175-
&case.msg, DOMAIN,
179+
let g = <G2Projective as HashToCurve<ExpandMsgXmd<Sha256>>>::hash_to_curve(
180+
[case.msg],
181+
case.dst,
176182
);
177-
let g_uncompressed = G2Affine::from(g).to_uncompressed();
178-
179-
assert_eq!(case.expected(), hex::encode(&g_uncompressed[..]));
183+
let aff = G2Affine::from(g);
184+
let g_uncompressed = aff.to_uncompressed();
185+
case.check_output(&g_uncompressed);
180186
}
181187
}

0 commit comments

Comments
 (0)
Please sign in to comment.