snarkvm_console_algorithms/blake2xs/
hash_to_curve.rs1use super::*;
17use snarkvm_console_types::prelude::AffineCurve;
18
19impl Blake2Xs {
20 #[inline]
22 pub fn hash_to_curve<G: AffineCurve>(input: &str) -> (G, String, usize) {
23 for k in 0..128 {
25 let message = format!("{input} in {k}");
27
28 if let Some(g) = Self::try_hash_to_curve::<G>(&message) {
30 return (g, message, k);
31 }
32 }
33
34 panic!("Unable to hash to curve on {input}")
36 }
37
38 #[inline]
40 fn try_hash_to_curve<G: AffineCurve>(input: &str) -> Option<G> {
41 let serialized_size = G::prime_subgroup_generator().compressed_size();
42
43 let digest = Self::evaluate(input.as_bytes(), u16::try_from(serialized_size).unwrap(), "AleoHtC0".as_bytes());
45 debug_assert!(digest.len() == serialized_size); G::from_random_bytes(&digest).and_then(|g| {
47 debug_assert!(g.is_on_curve());
48
49 let g = g.mul_by_cofactor();
50 debug_assert!(g.is_on_curve());
51 debug_assert!(g.is_in_correct_subgroup_assuming_on_curve());
52
53 (!g.is_zero()).then_some(g)
54 })
55 }
56}
57
58#[cfg(test)]
59mod bls12_377_g1 {
60 use super::*;
61 use snarkvm_curves::bls12_377::G1Affine;
62 use snarkvm_fields::PrimeField;
63 use snarkvm_utilities::{BigInteger384, CanonicalSerialize};
64
65 #[test]
66 fn hash_bls12_377_g1() {
67 let g1 = Blake2Xs::try_hash_to_curve::<G1Affine>("Aleo BLS12-377 G1 in 0").unwrap();
68 assert!(g1.is_on_curve());
69 assert!(g1.is_in_correct_subgroup_assuming_on_curve());
70 assert_eq!(g1.compressed_size(), 384 / 8);
71 assert_eq!(
72 Blake2Xs::hash_to_curve::<G1Affine>("Aleo BLS12-377 G1"),
73 (g1, "Aleo BLS12-377 G1 in 0".to_string(), 0)
74 );
75
76 assert_eq!(
78 g1.x.to_string(),
79 "89363714989903307245735717098563574705733591463163614225748337416674727625843187853442697973404985688481508350822",
80 );
81 assert_eq!(
82 g1.y.to_string(),
83 "3702177272937190650578065972808860481433820514072818216637796320125658674906330993856598323293086021583822603349",
84 );
85
86 assert_eq!(
88 g1.x.to_bigint(),
89 BigInteger384::new([
90 1089863619676461926,
91 2031922408020517912,
92 7605803015099675459,
93 5499508099818543095,
94 11627353473000952893,
95 41837199143568307
96 ])
97 );
98 assert_eq!(
99 g1.y.to_bigint(),
100 BigInteger384::new([
101 8946822147630122069,
102 11486725844942458959,
103 17739430126876114892,
104 5672784675232650440,
105 942928816728936680,
106 1733239579958889
107 ])
108 );
109
110 assert_eq!(
112 g1.x.0,
113 BigInteger384::new([
114 1171681672315280277,
115 6528257384425852712,
116 7514971432460253787,
117 2032708395764262463,
118 12876543207309632302,
119 107509843840671767
120 ])
121 );
122 assert_eq!(
123 g1.y.0,
124 BigInteger384::new([
125 13572190014569192121,
126 15344828677741220784,
127 17067903700058808083,
128 10342263224753415805,
129 1083990386877464092,
130 21335464879237822
131 ])
132 );
133
134 assert_eq!(G1Affine::prime_subgroup_generator(), g1);
136 }
137}
138
139#[cfg(test)]
140mod bls12_377_g2 {
141 use super::*;
142 use snarkvm_curves::bls12_377::G2Affine;
143 use snarkvm_fields::PrimeField;
144 use snarkvm_utilities::{BigInteger384, CanonicalSerialize};
145
146 #[test]
147 fn hash_bls12_377_g2() {
148 let g2 = Blake2Xs::try_hash_to_curve::<G2Affine>("Aleo BLS12-377 G2 in 6").unwrap();
149 assert!(g2.is_on_curve());
150 assert!(g2.is_in_correct_subgroup_assuming_on_curve());
151 assert_eq!(g2.compressed_size(), 2 * 384 / 8);
152 assert_eq!(
153 Blake2Xs::hash_to_curve::<G2Affine>("Aleo BLS12-377 G2"),
154 (g2, "Aleo BLS12-377 G2 in 6".to_string(), 6),
155 );
156
157 assert_eq!(
159 g2.x.to_string(),
160 "Fp2(170590608266080109581922461902299092015242589883741236963254737235977648828052995125541529645051927918098146183295 + 83407003718128594709087171351153471074446327721872642659202721143408712182996929763094113874399921859453255070254 * u)",
161 );
162 assert_eq!(
163 g2.y.to_string(),
164 "Fp2(1843833842842620867708835993770650838640642469700861403869757682057607397502738488921663703124647238454792872005 + 33145532013610981697337930729788870077912093258611421158732879580766461459275194744385880708057348608045241477209 * u)",
165 );
166
167 assert_eq!(
169 g2.x.c0.to_bigint(),
170 BigInteger384::new([
171 6285382596397680767,
172 15748827462709656851,
173 12106939604663586443,
174 15333984969116343459,
175 5478119782678835813,
176 79865001705186672
177 ])
178 );
179 assert_eq!(
180 g2.x.c1.to_bigint(),
181 BigInteger384::new([
182 16087313950742852142,
183 593255854261604337,
184 1941199260866950545,
185 10849744434273544618,
186 2633370935305329371,
187 39048459712288691
188 ])
189 );
190 assert_eq!(
191 g2.y.c0.to_bigint(),
192 BigInteger384::new([
193 7702421029866889285,
194 16004466681641276576,
195 106615717155384672,
196 763522394023763305,
197 16530696304726864408,
198 863223330401754
199 ])
200 );
201 assert_eq!(
202 g2.y.c1.to_bigint(),
203 BigInteger384::new([
204 14642269910726223961,
205 418400088670236579,
206 13367772290999385514,
207 12034951455731096578,
208 1807164704891090155,
209 15517665349181582
210 ])
211 );
212
213 assert_eq!(
215 g2.x.c0.0,
216 BigInteger384::new([
217 1394603105513884269,
218 11069732150289508451,
219 4261960060090787184,
220 13457254148541472797,
221 3177258746859163322,
222 82258727112085846
223 ])
224 );
225 assert_eq!(
226 g2.x.c1.0,
227 BigInteger384::new([
228 12672065269715576738,
229 3451530808602826578,
230 9486610028138952262,
231 5031487885431614078,
232 9858745210421513581,
233 63301617551232910
234 ])
235 );
236 assert_eq!(
237 g2.y.c0.0,
238 BigInteger384::new([
239 1855632670224768760,
240 2989378521406112342,
241 9748867374972564648,
242 3204895972998458874,
243 16520689795595505429,
244 61918742406142643
245 ])
246 );
247 assert_eq!(
248 g2.y.c1.0,
249 BigInteger384::new([
250 1532128906028652860,
251 14539073382194201855,
252 10828918286556702479,
253 14664598863867299115,
254 483199896405477997,
255 73741830940675480
256 ])
257 );
258
259 assert_eq!(G2Affine::prime_subgroup_generator(), g2);
261 }
262}
263
264#[cfg(test)]
265mod edwards_bls12 {
266 use super::*;
267 use snarkvm_curves::edwards_bls12::EdwardsAffine;
268 use snarkvm_fields::PrimeField;
269 use snarkvm_utilities::{BigInteger256, CanonicalSerialize};
270
271 #[test]
272 fn hash_edwards_bls12() {
273 let group = Blake2Xs::try_hash_to_curve::<EdwardsAffine>("Aleo Edwards BLS12 in 4").unwrap();
274 assert!(group.is_on_curve());
275 assert!(group.is_in_correct_subgroup_assuming_on_curve());
276 assert_eq!(group.compressed_size(), 256 / 8);
277 assert_eq!(
278 Blake2Xs::hash_to_curve::<EdwardsAffine>("Aleo Edwards BLS12"),
279 (group, "Aleo Edwards BLS12 in 4".to_string(), 4)
280 );
281
282 assert_eq!(group.x.to_string(), "1540945439182663264862696551825005342995406165131907382295858612069623286213",);
284 assert_eq!(group.y.to_string(), "8003546896475222703853313610036801932325312921786952001586936882361378122196",);
285
286 assert_eq!(
288 group.x.to_bigint(),
289 BigInteger256::new([1404703638504229317, 16672475576000152563, 1635533132911366150, 245486771465834503]),
290 "\n\nExpected: {:?}\n\n",
291 group.x.to_bigint().0,
292 );
293 assert_eq!(
294 group.y.to_bigint(),
295 BigInteger256::new([15352153743387634132, 9180404173643694677, 4017395716581932261, 1275038582114391971]),
296 "\n\nExpected: {:?}\n\n",
297 group.y.to_bigint().0,
298 );
299
300 assert_eq!(
302 group.x.0,
303 BigInteger256::new([15976313411695170452, 17230178952810798400, 11626259175167078036, 678729006091608048]),
304 "\n\nExpected: {:?}\n\n",
305 group.x.0,
306 );
307 assert_eq!(
308 group.y.0,
309 BigInteger256::new([926786653590077393, 18147000980977651608, 13077459464847727671, 1231472949076376191]),
310 "\n\nExpected: {:?}\n\n",
311 group.y.0,
312 );
313
314 assert_eq!(EdwardsAffine::prime_subgroup_generator(), group);
316 }
317}