@@ -7,7 +7,7 @@ use crate::{
77use core:: {
88 cmp:: Ordering ,
99 fmt:: Debug ,
10- ops:: { Add , Mul , Sub } ,
10+ ops:: { Add , Mul , Neg , Sub } ,
1111} ;
1212
1313/// Bls12_381 provides access to curve and field arithmetics on the BLS12-381
@@ -16,6 +16,54 @@ pub struct Bls12_381 {
1616 env : Env ,
1717}
1818
19+ fn sbb_for_sub_with_borrow ( a : & mut u64 , b : u64 , borrow : u8 ) -> u8 {
20+ let tmp = ( 1u128 << 64 ) + ( * a as u128 ) - ( b as u128 ) - ( borrow as u128 ) ;
21+ * a = tmp as u64 ;
22+ u8:: from ( tmp >> 64 == 0 )
23+ }
24+
25+ #[ derive( Debug ) ]
26+ pub ( crate ) struct BigInt < const N : usize > ( pub [ u64 ; N ] ) ;
27+
28+ impl < const N : usize > BigInt < N > {
29+ pub fn sub_with_borrow ( & mut self , other : & Self ) -> bool {
30+ let mut borrow = 0 ;
31+ for i in 0 ..N {
32+ borrow = sbb_for_sub_with_borrow ( & mut self . 0 [ i] , other. 0 [ i] , borrow) ;
33+ }
34+ borrow != 0
35+ }
36+
37+ pub fn copy_into_slice ( & self , slice : & mut [ u8 ] ) {
38+ if slice. len ( ) != N * 8 {
39+ sdk_panic ! ( "BigInt::copy_into_slice with mismatched slice length" )
40+ }
41+ for i in 0 ..N {
42+ let limb_bytes = self . 0 [ N - 1 - i] . to_be_bytes ( ) ;
43+ slice[ i * 8 ..( i + 1 ) * 8 ] . copy_from_slice ( & limb_bytes) ;
44+ }
45+ }
46+ }
47+
48+ impl < const N : usize , const M : usize > Into < BigInt < N > > for BytesN < M > {
49+ fn into ( self ) -> BigInt < N > {
50+ if M != N * 8 {
51+ sdk_panic ! ( "BytesN::Into<BigInt> - length mismatch" )
52+ }
53+
54+ let array = self . to_array ( ) ;
55+ let mut limbs = [ 0u64 ; N ] ;
56+ for i in 0 ..N {
57+ let start = i * 8 ;
58+ let end = start + 8 ;
59+ let mut bytes = [ 0u8 ; 8 ] ;
60+ bytes. copy_from_slice ( & array[ start..end] ) ;
61+ limbs[ N - 1 - i] = u64:: from_be_bytes ( bytes) ;
62+ }
63+ BigInt ( limbs)
64+ }
65+ }
66+
1967/// `G1Affine` is a point in the G1 group (subgroup defined over the base field
2068/// `Fq`) of the BLS12-381 elliptic curve
2169///
@@ -101,6 +149,57 @@ impl_bytesn_repr!(G2Affine, 192);
101149impl_bytesn_repr ! ( Fp , 48 ) ;
102150impl_bytesn_repr ! ( Fp2 , 96 ) ;
103151
152+ impl Fp {
153+ pub fn env ( & self ) -> & Env {
154+ self . 0 . env ( )
155+ }
156+
157+ pub fn map_to_g1 ( & self ) -> G1Affine {
158+ self . env ( ) . crypto ( ) . bls12_381 ( ) . map_fp_to_g1 ( self )
159+ }
160+ }
161+
162+ impl Into < BigInt < 6 > > for Fp {
163+ fn into ( self ) -> BigInt < 6 > {
164+ let inner: Bytes = self . 0 . into ( ) ;
165+ let mut limbs = [ 0u64 ; 6 ] ;
166+ for i in 0 ..6u32 {
167+ let start = i * 8 ;
168+ let mut slice = [ 0u8 ; 8 ] ;
169+ inner. slice ( start..start + 8 ) . copy_into_slice ( & mut slice) ;
170+ limbs[ 5 - i as usize ] = u64:: from_be_bytes ( slice) ;
171+ }
172+ BigInt ( limbs)
173+ }
174+ }
175+
176+ impl Neg for Fp {
177+ type Output = Fp ;
178+
179+ fn neg ( self ) -> Self :: Output {
180+ if self . to_array ( ) == [ 0 ; 48 ] {
181+ return self ;
182+ }
183+
184+ let env = self . env ( ) . clone ( ) ;
185+ let fp_bigint: BigInt < 6 > = self . 0 . into ( ) ;
186+ // BLS12-381 base field modulus
187+ let mut res = BigInt ( [
188+ 13402431016077863595 ,
189+ 2210141511517208575 ,
190+ 7435674573564081700 ,
191+ 7239337960414712511 ,
192+ 5412103778470702295 ,
193+ 1873798617647539866 ,
194+ ] ) ;
195+ // Compute modulus - value
196+ res. sub_with_borrow ( & fp_bigint) ;
197+ let mut bytes = [ 0u8 ; 48 ] ;
198+ res. copy_into_slice ( & mut bytes) ;
199+ Fp :: from_array ( & env, & bytes)
200+ }
201+ }
202+
104203impl G1Affine {
105204 pub fn env ( & self ) -> & Env {
106205 self . 0 . env ( )
@@ -131,6 +230,45 @@ impl Mul<Fr> for G1Affine {
131230 }
132231}
133232
233+ impl Neg for G1Affine {
234+ type Output = G1Affine ;
235+
236+ fn neg ( self ) -> Self :: Output {
237+ let mut inner: Bytes = self . 0 . into ( ) ;
238+ let y = Fp :: try_from_val ( inner. env ( ) , inner. slice ( 48 ..) . as_val ( ) ) . unwrap_optimized ( ) ;
239+ let neg_y = -y;
240+ inner. copy_from_slice ( 48 , & neg_y. to_array ( ) ) ;
241+ G1Affine :: from_bytes ( BytesN :: try_from_val ( inner. env ( ) , inner. as_val ( ) ) . unwrap_optimized ( ) )
242+ }
243+ }
244+
245+ impl Fp2 {
246+ pub fn env ( & self ) -> & Env {
247+ self . 0 . env ( )
248+ }
249+
250+ pub fn map_to_g2 ( & self ) -> G2Affine {
251+ self . env ( ) . crypto ( ) . bls12_381 ( ) . map_fp2_to_g2 ( self )
252+ }
253+ }
254+
255+ impl Neg for Fp2 {
256+ type Output = Fp2 ;
257+
258+ fn neg ( self ) -> Self :: Output {
259+ let mut inner = self . to_array ( ) ;
260+ let mut slice0 = [ 0 ; 48 ] ;
261+ let mut slice1 = [ 0 ; 48 ] ;
262+ slice0. copy_from_slice ( & inner[ 0 ..48 ] ) ;
263+ slice1. copy_from_slice ( & inner[ 48 ..96 ] ) ;
264+ let c0 = -Fp :: from_array ( self . env ( ) , & slice0) ;
265+ let c1 = -Fp :: from_array ( self . env ( ) , & slice1) ;
266+ inner[ 0 ..48 ] . copy_from_slice ( & c0. to_array ( ) ) ;
267+ inner[ 48 ..96 ] . copy_from_slice ( & c1. to_array ( ) ) ;
268+ Fp2 :: from_array ( self . env ( ) , & inner)
269+ }
270+ }
271+
134272impl G2Affine {
135273 pub fn env ( & self ) -> & Env {
136274 self . 0 . env ( )
@@ -161,23 +299,15 @@ impl Mul<Fr> for G2Affine {
161299 }
162300}
163301
164- impl Fp {
165- pub fn env ( & self ) -> & Env {
166- self . 0 . env ( )
167- }
168-
169- pub fn map_to_g1 ( & self ) -> G1Affine {
170- self . env ( ) . crypto ( ) . bls12_381 ( ) . map_fp_to_g1 ( self )
171- }
172- }
173-
174- impl Fp2 {
175- pub fn env ( & self ) -> & Env {
176- self . 0 . env ( )
177- }
302+ impl Neg for G2Affine {
303+ type Output = G2Affine ;
178304
179- pub fn map_to_g2 ( & self ) -> G2Affine {
180- self . env ( ) . crypto ( ) . bls12_381 ( ) . map_fp2_to_g2 ( self )
305+ fn neg ( self ) -> Self :: Output {
306+ let mut inner: Bytes = self . 0 . into ( ) ;
307+ let y = Fp2 :: try_from_val ( inner. env ( ) , inner. slice ( 96 ..) . as_val ( ) ) . unwrap_optimized ( ) ;
308+ let neg_y = -y;
309+ inner. copy_from_slice ( 96 , & neg_y. to_array ( ) ) ;
310+ G2Affine :: from_bytes ( BytesN :: try_from_val ( inner. env ( ) , inner. as_val ( ) ) . unwrap_optimized ( ) )
181311 }
182312}
183313
0 commit comments