commonware_cryptography/bls12381/primitives/
group.rs1use blst::{
14 blst_bendian_from_scalar, blst_fp12, blst_fr, blst_fr_add, blst_fr_from_scalar,
15 blst_fr_from_uint64, blst_fr_inverse, blst_fr_mul, blst_fr_sub, blst_hash_to_g1,
16 blst_hash_to_g2, blst_keygen, blst_p1, blst_p1_add_or_double, blst_p1_affine, blst_p1_compress,
17 blst_p1_from_affine, blst_p1_in_g1, blst_p1_is_inf, blst_p1_mult, blst_p1_to_affine,
18 blst_p1_uncompress, blst_p2, blst_p2_add_or_double, blst_p2_affine, blst_p2_compress,
19 blst_p2_from_affine, blst_p2_in_g2, blst_p2_is_inf, blst_p2_mult, blst_p2_to_affine,
20 blst_p2_uncompress, blst_scalar, blst_scalar_from_bendian, blst_scalar_from_fr, blst_sk_check,
21 Pairing, BLS12_381_G1, BLS12_381_G2, BLS12_381_NEG_G1, BLST_ERROR,
22};
23use commonware_utils::SizedSerialize;
24use rand::RngCore;
25use std::ptr;
26use zeroize::Zeroize;
27
28pub type DST = &'static [u8];
32
33pub trait Element: Clone + Eq + PartialEq + Send + Sync {
35 fn zero() -> Self;
37
38 fn one() -> Self;
40
41 fn add(&mut self, rhs: &Self);
43
44 fn mul(&mut self, rhs: &Scalar);
46
47 fn serialize(&self) -> Vec<u8>;
49
50 fn size() -> usize;
52
53 fn deserialize(bytes: &[u8]) -> Option<Self>;
58}
59
60pub trait Point: Element {
62 fn map(&mut self, dst: DST, message: &[u8]);
64}
65
66#[derive(Debug, Clone, Copy, Eq, PartialEq)]
68#[repr(transparent)]
69pub struct Scalar(blst_fr);
70
71const SCALAR_LENGTH: usize = 32;
73
74const BLST_FR_ONE: Scalar = Scalar(blst_fr {
87 l: [
88 0x0000_0001_ffff_fffe,
89 0x5884_b7fa_0003_4802,
90 0x998c_4fef_ecbc_4ff5,
91 0x1824_b159_acc5_056f,
92 ],
93});
94
95#[derive(Debug, Clone, Copy, Eq, PartialEq)]
97#[repr(transparent)]
98pub struct G1(blst_p1);
99
100pub const G1_ELEMENT_BYTE_LENGTH: usize = 48;
102
103pub const G1_PROOF_OF_POSSESSION: DST = b"BLS_POP_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_";
105
106pub const G1_MESSAGE: DST = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_";
113
114#[derive(Debug, Clone, Copy, Eq, PartialEq)]
116#[repr(transparent)]
117pub struct G2(blst_p2);
118
119pub const G2_ELEMENT_BYTE_LENGTH: usize = 96;
121
122pub const G2_PROOF_OF_POSSESSION: DST = b"BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
124
125pub const G2_MESSAGE: DST = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
132
133#[derive(Debug, Clone, Copy, Eq, PartialEq)]
138pub struct GT(blst_fp12);
139
140pub type Private = Scalar;
142
143pub const PRIVATE_KEY_LENGTH: usize = SCALAR_LENGTH;
145
146pub type Public = G1;
148
149pub const PUBLIC_KEY_LENGTH: usize = G1_ELEMENT_BYTE_LENGTH;
151
152pub type Signature = G2;
154
155pub const SIGNATURE_LENGTH: usize = G2_ELEMENT_BYTE_LENGTH;
157
158pub const PROOF_OF_POSSESSION: DST = G2_PROOF_OF_POSSESSION;
160
161pub const MESSAGE: DST = G2_MESSAGE;
163
164fn bits(scalar: &blst_scalar) -> usize {
166 let mut bits: usize = SCALAR_LENGTH * 8;
167 for i in scalar.b.iter().rev() {
168 let leading = i.leading_zeros();
169 bits -= leading as usize;
170 if leading < 8 {
171 break;
172 }
173 }
174 bits
175}
176
177#[derive(Debug, Clone, PartialEq, Copy)]
179pub struct Share {
180 pub index: u32,
182 pub private: Private,
184}
185
186impl Share {
187 pub fn public(&self) -> Public {
191 let mut public = <Public as Element>::one();
192 public.mul(&self.private);
193 public
194 }
195
196 pub fn serialize(&self) -> Vec<u8> {
198 let mut bytes = [0u8; u32::SERIALIZED_LEN + SCALAR_LENGTH];
199 bytes[..u32::SERIALIZED_LEN].copy_from_slice(&self.index.to_be_bytes());
200 bytes[u32::SERIALIZED_LEN..].copy_from_slice(&self.private.serialize());
201 bytes.to_vec()
202 }
203
204 pub fn deserialize(bytes: &[u8]) -> Option<Self> {
206 if bytes.len() != u32::SERIALIZED_LEN + SCALAR_LENGTH {
207 return None;
208 }
209 let index = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
210 let private = Private::deserialize(&bytes[u32::SERIALIZED_LEN..])?;
211 Some(Self { index, private })
212 }
213}
214
215impl Scalar {
216 pub fn rand<R: RngCore>(rng: &mut R) -> Self {
218 let mut ikm = [0u8; 64];
220 rng.fill_bytes(&mut ikm);
221
222 let mut ret = blst_fr::default();
224 unsafe {
225 let mut sc = blst_scalar::default();
226 blst_keygen(&mut sc, ikm.as_ptr(), ikm.len(), ptr::null(), 0);
227 blst_fr_from_scalar(&mut ret, &sc);
228 }
229
230 ikm.zeroize();
232 Self(ret)
233 }
234
235 pub fn set_int(&mut self, i: u32) {
237 let buffer = [i as u64, 0, 0, 0];
242 unsafe { blst_fr_from_uint64(&mut self.0, buffer.as_ptr()) };
243 }
244
245 pub fn inverse(&self) -> Option<Self> {
247 if *self == Self::zero() {
248 return None;
249 }
250 let mut ret = blst_fr::default();
251 unsafe { blst_fr_inverse(&mut ret, &self.0) };
252 Some(Self(ret))
253 }
254
255 pub fn sub(&mut self, rhs: &Self) {
257 unsafe { blst_fr_sub(&mut self.0, &self.0, &rhs.0) }
258 }
259}
260
261impl Zeroize for Scalar {
262 fn zeroize(&mut self) {
263 self.0.l.zeroize();
264 }
265}
266
267impl Element for Scalar {
268 fn zero() -> Self {
269 Self(blst_fr::default())
270 }
271
272 fn one() -> Self {
273 BLST_FR_ONE
274 }
275
276 fn add(&mut self, rhs: &Self) {
277 unsafe {
278 blst_fr_add(&mut self.0, &self.0, &rhs.0);
279 }
280 }
281
282 fn mul(&mut self, rhs: &Self) {
283 unsafe {
284 blst_fr_mul(&mut self.0, &self.0, &rhs.0);
285 }
286 }
287
288 fn serialize(&self) -> Vec<u8> {
289 let mut bytes = [0u8; SCALAR_LENGTH];
290 unsafe {
291 let mut scalar = blst_scalar::default();
292 blst_scalar_from_fr(&mut scalar, &self.0);
293 blst_bendian_from_scalar(bytes.as_mut_ptr(), &scalar);
294 }
295 bytes.to_vec()
296 }
297
298 fn deserialize(bytes: &[u8]) -> Option<Self> {
299 if bytes.len() != SCALAR_LENGTH {
300 return None;
301 }
302 let mut ret = blst_fr::default();
303 unsafe {
304 let mut scalar = blst_scalar::default();
305 blst_scalar_from_bendian(&mut scalar, bytes.as_ptr());
306 if !blst_sk_check(&scalar) {
316 return None;
317 }
318 blst_fr_from_scalar(&mut ret, &scalar);
319 }
320 Some(Self(ret))
321 }
322
323 fn size() -> usize {
324 SCALAR_LENGTH
325 }
326}
327
328impl Element for G1 {
329 fn zero() -> Self {
330 Self(blst_p1::default())
331 }
332
333 fn one() -> Self {
334 let mut ret = blst_p1::default();
335 unsafe {
336 blst_p1_from_affine(&mut ret, &BLS12_381_G1);
337 }
338 Self(ret)
339 }
340
341 fn add(&mut self, rhs: &Self) {
342 unsafe {
343 blst_p1_add_or_double(&mut self.0, &self.0, &rhs.0);
344 }
345 }
346
347 fn mul(&mut self, rhs: &Scalar) {
348 let mut scalar: blst_scalar = blst_scalar::default();
349 unsafe {
350 blst_scalar_from_fr(&mut scalar, &rhs.0);
351 blst_p1_mult(&mut self.0, &self.0, scalar.b.as_ptr(), bits(&scalar));
352 }
353 }
354
355 fn serialize(&self) -> Vec<u8> {
356 let mut bytes = [0u8; G1_ELEMENT_BYTE_LENGTH];
357 unsafe {
358 blst_p1_compress(bytes.as_mut_ptr(), &self.0);
359 }
360 bytes.to_vec()
361 }
362
363 fn deserialize(bytes: &[u8]) -> Option<Self> {
364 if bytes.len() != G1_ELEMENT_BYTE_LENGTH {
365 return None;
366 }
367 let mut ret = blst_p1::default();
368 unsafe {
369 let mut affine = blst_p1_affine::default();
370 if blst_p1_uncompress(&mut affine, bytes.as_ptr()) != BLST_ERROR::BLST_SUCCESS {
371 return None;
372 }
373 blst_p1_from_affine(&mut ret, &affine);
374
375 if blst_p1_is_inf(&ret) {
377 return None;
378 }
379
380 if !blst_p1_in_g1(&ret) {
382 return None;
383 }
384 }
385 Some(Self(ret))
386 }
387
388 fn size() -> usize {
389 G1_ELEMENT_BYTE_LENGTH
390 }
391}
392
393impl Point for G1 {
394 fn map(&mut self, dst: DST, data: &[u8]) {
395 unsafe {
396 blst_hash_to_g1(
397 &mut self.0,
398 data.as_ptr(),
399 data.len(),
400 dst.as_ptr(),
401 dst.len(),
402 ptr::null(),
403 0,
404 );
405 }
406 }
407}
408
409impl Element for G2 {
410 fn zero() -> Self {
411 Self(blst_p2::default())
412 }
413
414 fn one() -> Self {
415 let mut ret = blst_p2::default();
416 unsafe {
417 blst_p2_from_affine(&mut ret, &BLS12_381_G2);
418 }
419 Self(ret)
420 }
421
422 fn add(&mut self, rhs: &Self) {
423 unsafe {
424 blst_p2_add_or_double(&mut self.0, &self.0, &rhs.0);
425 }
426 }
427
428 fn mul(&mut self, rhs: &Scalar) {
429 let mut scalar = blst_scalar::default();
430 unsafe {
431 blst_scalar_from_fr(&mut scalar, &rhs.0);
432 blst_p2_mult(&mut self.0, &self.0, scalar.b.as_ptr(), bits(&scalar));
433 }
434 }
435
436 fn serialize(&self) -> Vec<u8> {
437 let mut bytes = [0u8; G2_ELEMENT_BYTE_LENGTH];
438 unsafe {
439 blst_p2_compress(bytes.as_mut_ptr(), &self.0);
440 }
441 bytes.to_vec()
442 }
443
444 fn deserialize(bytes: &[u8]) -> Option<Self> {
445 if bytes.len() != G2_ELEMENT_BYTE_LENGTH {
446 return None;
447 }
448 let mut ret = blst_p2::default();
449 unsafe {
450 let mut affine = blst_p2_affine::default();
451 if blst_p2_uncompress(&mut affine, bytes.as_ptr()) != BLST_ERROR::BLST_SUCCESS {
452 return None;
453 }
454 blst_p2_from_affine(&mut ret, &affine);
455
456 if blst_p2_is_inf(&ret) {
458 return None;
459 }
460
461 if !blst_p2_in_g2(&ret) {
463 return None;
464 }
465 }
466 Some(Self(ret))
467 }
468
469 fn size() -> usize {
470 G2_ELEMENT_BYTE_LENGTH
471 }
472}
473
474impl Point for G2 {
475 fn map(&mut self, dst: DST, data: &[u8]) {
476 unsafe {
477 blst_hash_to_g2(
478 &mut self.0,
479 data.as_ptr(),
480 data.len(),
481 dst.as_ptr(),
482 dst.len(),
483 ptr::null(),
484 0,
485 );
486 }
487 }
488}
489
490pub(super) fn equal(pk: &G1, sig: &G2, hm: &G2) -> bool {
493 let mut pairing = Pairing::new(false, &[]);
497
498 let mut q = blst_p2_affine::default();
500 unsafe {
501 blst_p2_to_affine(&mut q, &sig.0);
502 pairing.raw_aggregate(&q, &BLS12_381_NEG_G1);
503 }
504
505 let mut p = blst_p1_affine::default();
507 let mut q = blst_p2_affine::default();
508 unsafe {
509 blst_p1_to_affine(&mut p, &pk.0);
510 blst_p2_to_affine(&mut q, &hm.0);
511 }
512
513 pairing.raw_aggregate(&q, &p);
515
516 pairing.commit();
521 pairing.finalverify(None)
522}
523
524#[cfg(test)]
525mod tests {
526 use super::*;
527 use rand::prelude::*;
528
529 #[test]
530 fn basic_group() {
531 let s = Scalar::rand(&mut thread_rng());
533 let mut e1 = s;
534 let e2 = s;
535 let mut s2 = s;
536 s2.add(&s);
537 s2.mul(&s);
538 e1.add(&e2);
539 e1.mul(&e2);
540
541 let mut p1 = G1::zero();
543 p1.mul(&s2);
544
545 let mut p2 = G1::zero();
547 p2.mul(&s);
548 p2.add(&p2.clone());
549 assert_eq!(p1, p2);
550 }
551}