1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//! Module implementing the high level structures for manipulating
//! MCL points and scalars.
//!
//! # Examples
//! ```
//! // Schnorr identification scheme.
//! // Prover wants to show to the Verifier that he knows the secret key,
//! use mcl::{init, bn::{Fr, G1}};
//! 
//! // Always initialize the library first.
//! init::init_curve(init::Curve::Bls12_381);
//!
//! // choose the generators for both of the groups
//! let g = G1::hash_and_map(b"something").unwrap();
//!
//! // setup the keys
//! let sk = Fr::from_csprng();
//! let pk = &g * &sk;
//!
//! // initialize ephemerals (done by the Prover)
//! let x = Fr::from_csprng();
//! let commitment = &g * &x;
//!
//! // generate challenge (done by the Verifier)
//! let c = Fr::from_csprng();
//!
//! // compute the response (done by the Prover)
//! let s = x + &sk * &c;
//!
//! // verify the proof (done by the Verifier)
//! assert_eq!(&g * s, &commitment + pk * &c);
//! ```

use crate::{ffi::*, traits::*, common::Base};

use std::ops::{Add, Mul, Sub, Div};
use mcl_derive::*;

#[derive(Object, ScalarPoint, Random)]
#[derive(Default, Debug, Clone, Copy)]
pub struct Fp {
    inner: MclBnFp,
}

#[derive(Object, ScalarPoint)]
#[derive(Default, Debug, Clone, Copy)]
pub struct Fp2 {
    inner: MclBnFp2,
}

#[derive(Object, ScalarPoint, Formattable, Random)]
#[derive(Default, Debug, Clone, Copy)]
pub struct Fr {
    inner: MclBnFr,
}

#[derive(Object, AdditivePoint, Formattable)]
#[derive(Default, Debug, Clone)]
pub struct G1 {
    inner: MclBnG1,
}

#[derive(Object, AdditivePoint, Formattable)]
#[derive(Default, Debug, Clone)]
pub struct G2 {
    inner: MclBnG2,
}

#[derive(Object, MultiplicativePoint, Formattable)]
#[derive(Default, Debug, Clone)]
pub struct GT {
    inner: MclBnGT,
}

impl GT {
    pub fn from_pairing(p: &G1, q: &G2) -> GT {
        let mut result = MclBnGT::default();
        unsafe {
            mclBn_pairing(
                &mut result as *mut MclBnGT,
                &p.inner as *const MclBnG1,
                &q.inner as *const MclBnG2,
            );
        }
        GT { inner: result }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::init;

    fn initialize() {
        init::init_curve(init::Curve::Bls12_381);
    }

    fn run_test(inner: impl FnOnce() -> ()) {
        initialize();
        inner();
    }

    #[test]
    fn test_mcl_bn_fp_str() {
        run_test(|| {
            let fr = Fr::from_str("123", Base::Dec);
            assert_eq!(fr.get_str(Base::Dec), "123".to_string());
        });
    }

    #[test]
    fn test_fp_mul() {
        run_test(|| {
            let a = Fr::from_str("12", Base::Dec);
            let b = Fr::from_str("13", Base::Dec);
            let c = Fr::from_str("156", Base::Dec);
            assert_eq!(a * b, c);
        });
    }

    #[test]
    fn test_g1_mul() {
        run_test(|| {
            let p = G1::hash_and_map(b"this").unwrap();
            let x = Fr::from_str("123", Base::Dec);
            let y = p * x;
            let expected = G1::from_str(
                "1 ea23afffe7e4eaeddbec067563e2387bac5c2354bd58f4346151db670e65c465f947789e5f82de9ba7567d0a289c658 cf01434515162c99815667f4a5515e20d407609702b9bc182155bcf23473960ec4de3b5b552285b3f1656948cfe3260",
                Base::Hex);
            assert_eq!(y, expected);
        });
    }

    #[test]
    fn test_pairing() {
        run_test(|| {
            let a = Fr::from_str("123", Base::Dec);
            let b = Fr::from_str("456", Base::Dec);
            let P = G1::hash_and_map(b"abc").unwrap();
            let Q = G2::hash_and_map(b"abc").unwrap();

            let e1 = GT::from_pairing(&P, &Q);

            let aQ = Q * &a;
            let bP = P * &b;

            let e2 = GT::from_pairing(&bP, &aQ);
            let e1 = e1.pow(&(&a * &b));
            assert_eq!(e1, e2);
        });
    }

    #[test]
    fn test_serde_raw() {
        run_test(|| {
            let a = Fr::from_str("123", Base::Dec);
            let mut after = Fr::default();
            after.deserialize_raw(&a.serialize_raw().unwrap()).unwrap();
            assert_eq!(a, after);
        });
    }
}