noah_algebra/bls12_381/
gt.rs1use crate::bls12_381::{BLSPairingEngine, BLSScalar, BLSG1, BLSG2};
2use crate::errors::AlgebraError;
3use crate::prelude::{derive_prng_from_hash, *};
4use crate::traits::Pairing;
5use ark_bls12_381::{Bls12_381, Fq12Config};
6use ark_ec::pairing::PairingOutput;
7use ark_ff::{BigInteger, Fp12, PrimeField};
8use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate};
9use ark_std::UniformRand;
10use digest::{consts::U64, Digest};
11use ruc::*;
12use wasm_bindgen::prelude::*;
13
14#[wasm_bindgen]
17#[derive(Copy, Default, Clone, PartialEq, Eq, Debug)]
18pub struct BLSGt(pub(crate) Fp12<Fq12Config>);
19
20impl Neg for BLSGt {
21 type Output = Self;
22
23 fn neg(self) -> Self::Output {
24 let mut v = self.0;
25 v.conjugate_in_place();
26 Self(v)
27 }
28}
29
30impl<'a> Add<&'a BLSGt> for BLSGt {
31 type Output = BLSGt;
32
33 #[inline]
34 fn add(self, rhs: &'a BLSGt) -> Self::Output {
35 Self(self.0.mul(&rhs.0))
36 }
37}
38
39impl<'a> Sub<&'a BLSGt> for BLSGt {
40 type Output = BLSGt;
41
42 #[inline]
43 fn sub(self, rhs: &'a BLSGt) -> Self::Output {
44 let mut rhs_inverse = rhs.0.clone();
45 rhs_inverse.conjugate_in_place();
46
47 Self(self.0.mul(&rhs_inverse))
48 }
49}
50
51impl<'a> Mul<&'a BLSScalar> for BLSGt {
52 type Output = BLSGt;
53
54 fn mul(self, rhs: &'a BLSScalar) -> Self::Output {
55 let mut acc = Self::get_identity();
56
57 for bit in rhs
64 .0
65 .into_bigint()
66 .to_bytes_le()
67 .iter()
68 .rev()
69 .flat_map(|byte| (0..8).rev().map(move |i| ((byte >> i) & 1u8) == 1u8))
70 .skip(1)
71 {
72 acc = acc.double();
73 if bit {
74 acc = acc.add(&self)
75 }
76 }
77
78 acc
79 }
80}
81
82impl<'a> AddAssign<&'a BLSGt> for BLSGt {
83 #[inline]
84 fn add_assign(&mut self, rhs: &'a BLSGt) {
85 self.0.mul_assign(&rhs.0)
86 }
87}
88
89impl<'a> SubAssign<&'a BLSGt> for BLSGt {
90 #[inline]
91 fn sub_assign(&mut self, rhs: &'a BLSGt) {
92 let mut rhs_inverse = rhs.0.clone();
93 rhs_inverse.conjugate_in_place();
94
95 self.0.mul_assign(&rhs_inverse)
96 }
97}
98
99impl Group for BLSGt {
100 type ScalarType = BLSScalar;
101
102 const COMPRESSED_LEN: usize = 576;
103
104 #[inline]
105 fn double(&self) -> Self {
106 Self(self.0.mul(&self.0))
107 }
108
109 #[inline]
110 fn get_identity() -> Self {
111 Self(Fp12::<Fq12Config>::one())
112 }
113
114 #[inline]
115 fn get_base() -> Self {
116 BLSPairingEngine::pairing(&BLSG1::get_base(), &BLSG2::get_base())
117 }
118
119 #[inline]
120 fn random<R: CryptoRng + RngCore>(prng: &mut R) -> Self {
121 let g: PairingOutput<Bls12_381> = prng.gen();
122 Self(g.0)
123 }
124
125 #[inline]
126 fn to_compressed_bytes(&self) -> Vec<u8> {
127 let mut buf = Vec::new();
128 self.0.serialize_with_mode(&mut buf, Compress::Yes).unwrap();
129
130 buf
131 }
132
133 #[inline]
134 fn to_unchecked_bytes(&self) -> Vec<u8> {
135 let mut buf = Vec::new();
136 self.0.serialize_with_mode(&mut buf, Compress::No).unwrap();
137
138 buf
139 }
140
141 #[inline]
142 fn from_compressed_bytes(bytes: &[u8]) -> Result<Self> {
143 let mut reader = ark_std::io::BufReader::new(bytes);
144
145 let res =
146 Fp12::<Fq12Config>::deserialize_with_mode(&mut reader, Compress::Yes, Validate::Yes);
147
148 if res.is_ok() {
149 Ok(Self(res.unwrap()))
150 } else {
151 Err(eg!(AlgebraError::DeserializationError))
152 }
153 }
154
155 #[inline]
156 fn from_unchecked_bytes(bytes: &[u8]) -> Result<Self> {
157 let mut reader = ark_std::io::BufReader::new(bytes);
158
159 let res =
160 Fp12::<Fq12Config>::deserialize_with_mode(&mut reader, Compress::No, Validate::No);
161
162 if res.is_ok() {
163 Ok(Self(res.unwrap()))
164 } else {
165 Err(eg!(AlgebraError::DeserializationError))
166 }
167 }
168
169 #[inline]
170 fn unchecked_size() -> usize {
171 let g = Self::get_base().0;
172 g.serialized_size(Compress::No)
173 }
174
175 #[inline]
176 fn from_hash<D>(hash: D) -> Self
177 where
178 D: Digest<OutputSize = U64> + Default,
179 {
180 let mut prng = derive_prng_from_hash::<D>(hash);
181 Self(Fp12::<Fq12Config>::rand(&mut prng))
182 }
183}