noah_algebra/bls12_381/
gt.rs

1use 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/// The wrapped struct for [`Fp12<ark_bls12_381::Fq12Parameters>`](https://docs.rs/ark-bls12-381/0.3.0/ark_bls12_381/fq12/struct.Fq12Parameters.html),
15/// which is the pairing result
16#[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        // This is a simple double-and-add implementation of group element
58        // multiplication, moving from most significant to least
59        // significant bit of the scalar.
60        //
61        // We skip the leading bit because it's always unset for Fq
62        // elements.
63        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}