1use std::io::ErrorKind;
2
3use crate::{
4 syscall_bls12381_add, syscall_bls12381_decompress, syscall_bls12381_double,
5 utils::{AffinePoint, WeierstrassAffinePoint, WeierstrassPoint},
6};
7
8pub const N: usize = 12;
10
11#[derive(Copy, Clone)]
13#[repr(align(8))]
14pub struct Bls12381Point(pub WeierstrassPoint<N>);
15
16impl WeierstrassAffinePoint<N> for Bls12381Point {
17 fn infinity() -> Self {
18 Self(WeierstrassPoint::Infinity)
19 }
20
21 fn is_infinity(&self) -> bool {
22 matches!(self.0, WeierstrassPoint::Infinity)
23 }
24}
25
26impl AffinePoint<N> for Bls12381Point {
27 const GENERATOR: [u64; N] = [
28 18103045581585958587,
29 7806400890582735599,
30 11623291730934869080,
31 14080658508445169925,
32 2780237799254240271,
33 1725392847304644500,
34 912580534683953121,
35 15005087156090211044,
36 61670280795567085,
37 18227722000993880822,
38 11573741888802228964,
39 627113611842199793,
40 ];
41
42 #[allow(deprecated)]
46 const GENERATOR_T: Self = Self(WeierstrassPoint::Affine(Self::GENERATOR));
47
48 fn new(limbs: [u64; N]) -> Self {
49 Self(WeierstrassPoint::Affine(limbs))
50 }
51
52 fn identity() -> Self {
53 Self::infinity()
54 }
55
56 fn is_identity(&self) -> bool {
57 self.is_infinity()
58 }
59
60 fn limbs_ref(&self) -> &[u64; N] {
61 match &self.0 {
62 WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
63 WeierstrassPoint::Affine(limbs) => limbs,
64 }
65 }
66
67 fn limbs_mut(&mut self) -> &mut [u64; N] {
68 match &mut self.0 {
69 WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
70 WeierstrassPoint::Affine(limbs) => limbs,
71 }
72 }
73
74 fn add_assign(&mut self, other: &Self) {
75 let a = self.limbs_mut();
76 let b = other.limbs_ref();
77 unsafe {
78 syscall_bls12381_add(a, b);
79 }
80 }
81
82 fn complete_add_assign(&mut self, other: &Self) {
83 self.weierstrass_add_assign(other);
84 }
85
86 fn double(&mut self) {
87 let a = self.limbs_mut();
88 unsafe {
89 syscall_bls12381_double(a);
90 }
91 }
92}
93
94pub fn decompress_pubkey(compressed_key: &[u64; 6]) -> Result<[u64; 12], ErrorKind> {
96 let mut decompressed_key = [0u64; 12];
97 decompressed_key[..6].copy_from_slice(compressed_key);
98
99 let mut decompressed_key = decompressed_key.map(u64::to_ne_bytes);
101
102 const SIGN_OFFSET: u32 = 3;
104 const SIGN_MASK: u8 = 1u8 << (u8::BITS - SIGN_OFFSET);
105 let sign_bit = (decompressed_key[0][0] & SIGN_MASK) != 0;
106 decompressed_key[0][0] <<= SIGN_OFFSET;
107 decompressed_key[0][0] >>= SIGN_OFFSET;
108
109 let mut decompressed_key = decompressed_key.map(u64::from_ne_bytes);
110
111 unsafe {
112 syscall_bls12381_decompress(&mut decompressed_key, sign_bit);
113 }
114
115 Ok(decompressed_key)
116}