halo2curves_axiom/bls12_381/
endo.rs

1//! Source: <https://github.com/privacy-scaling-explorations/halo2curves/blob/support_bls12-381/src/bls12_381/mod.rs>
2
3use crate::arithmetic::mul_512;
4use crate::arithmetic::sbb;
5use crate::{
6    arithmetic::{CurveEndo, EndoParameters},
7    endo,
8};
9use ff::PrimeField;
10use ff::WithSmallOrderMulGroup;
11use std::convert::TryInto;
12
13use super::{G1Projective, Scalar};
14
15// Obtained from https://github.com/ConsenSys/gnark-crypto/blob/master/ecc/utils.go
16// See https://github.com/demining/Endomorphism-Secp256k1/blob/main/README.md
17// to have more details about the endomorphism.
18const ENDO_PARAMS_BLS: EndoParameters = EndoParameters {
19    // round(b2/n)
20    gamma2: [0x63f6e522f6cfee30u64, 0x7c6becf1e01faadd, 0x01, 0x0],
21    // round(-b1/n)
22    gamma1: [0x02u64, 0x0, 0x0, 0x0],
23    b1: [0x01u64, 0x0, 0x0, 0x0],
24    b2: [0x0000000100000000, 0xac45a4010001a402, 0x0, 0x0],
25};
26
27endo!(G1Projective, Scalar, ENDO_PARAMS_BLS);
28
29#[test]
30fn test_endo() {
31    use ff::Field;
32    use rand_core::OsRng;
33
34    for _ in 0..100000 {
35        let k = Scalar::random(OsRng);
36        let (k1, k1_neg, k2, k2_neg) = G1Projective::decompose_scalar(&k);
37        if k1_neg & k2_neg {
38            assert_eq!(
39                k,
40                -Scalar::from_u128(k1) + Scalar::ZETA * Scalar::from_u128(k2)
41            )
42        } else if k1_neg {
43            assert_eq!(
44                k,
45                -Scalar::from_u128(k1) - Scalar::ZETA * Scalar::from_u128(k2)
46            )
47        } else if k2_neg {
48            assert_eq!(
49                k,
50                Scalar::from_u128(k1) + Scalar::ZETA * Scalar::from_u128(k2)
51            )
52        } else {
53            assert_eq!(
54                k,
55                Scalar::from_u128(k1) - Scalar::ZETA * Scalar::from_u128(k2)
56            )
57        }
58    }
59
60    for _ in 0..100000 {
61        let k = Scalar::random(OsRng);
62        let (k1, k1_neg, k2, k2_neg) = G1Projective::decompose_scalar(&k);
63        if k1_neg & k2_neg {
64            assert_eq!(
65                k,
66                -Scalar::from_u128(k1) + Scalar::ZETA * Scalar::from_u128(k2)
67            )
68        } else if k1_neg {
69            assert_eq!(
70                k,
71                -Scalar::from_u128(k1) - Scalar::ZETA * Scalar::from_u128(k2)
72            )
73        } else if k2_neg {
74            assert_eq!(
75                k,
76                Scalar::from_u128(k1) + Scalar::ZETA * Scalar::from_u128(k2)
77            )
78        } else {
79            assert_eq!(
80                k,
81                Scalar::from_u128(k1) - Scalar::ZETA * Scalar::from_u128(k2)
82            )
83        }
84    }
85}