amcl_miracl/
bls.rs

1/*
2Licensed to the Apache Software Foundation (ASF) under one
3or more contributor license agreements.  See the NOTICE file
4distributed with this work for additional information
5regarding copyright ownership.  The ASF licenses this file
6to you under the Apache License, Version 2.0 (the
7"License"); you may not use this file except in compliance
8with the License.  You may obtain a copy of the License at
9
10  http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing,
13software distributed under the License is distributed on an
14"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15KIND, either express or implied.  See the License for the
16specific language governing permissions and limitations
17under the License.
18*/
19use super::ecp::ECP;
20use super::ecp2::ECP2;
21use std::str;
22//use super::fp12::FP12;
23use super::big;
24use super::big::BIG;
25use super::pair;
26use super::rom;
27
28use rand::RAND;
29use sha3::SHA3;
30use sha3::SHAKE256;
31
32/* BLS API Functions */
33
34pub const BFS: usize = big::MODBYTES as usize;
35pub const BGS: usize = big::MODBYTES as usize;
36pub const BLS_OK: isize = 0;
37pub const BLS_FAIL: isize = -1;
38
39/* hash a message to an ECP point, using SHA3 */
40
41#[allow(non_snake_case)]
42fn bls_hashit(m: &str) -> ECP {
43    let mut sh = SHA3::new(SHAKE256);
44    let mut hm: [u8; BFS] = [0; BFS];
45    let t = m.as_bytes();
46    for i in 0..m.len() {
47        sh.process(t[i]);
48    }
49    sh.shake(&mut hm, BFS);
50    let P = ECP::mapit(&hm);
51    return P;
52}
53
54/* generate key pair, private key s, public key w */
55pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
56    let q = BIG::new_ints(&rom::CURVE_ORDER);
57    let g = ECP2::generator();
58    let mut sc = BIG::randomnum(&q, &mut rng);
59    sc.tobytes(s);
60    pair::g2mul(&g, &mut sc).tobytes(w);
61    return BLS_OK;
62}
63
64/* Sign message m using private key s to produce signature sig */
65
66pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
67    let d = bls_hashit(m);
68    let mut sc = BIG::frombytes(&s);
69    pair::g1mul(&d, &mut sc).tobytes(sig, true);
70    return BLS_OK;
71}
72
73/* Verify signature given message m, the signature sig, and the public key w */
74
75pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
76    let hm = bls_hashit(m);
77    let mut d = ECP::frombytes(&sig);
78    let g = ECP2::generator();
79    let pk = ECP2::frombytes(&w);
80    d.neg();
81
82    // Use new multi-pairing mechanism
83    let mut r = pair::initmp();
84    pair::another(&mut r, &g, &d);
85    pair::another(&mut r, &pk, &hm);
86    let mut v = pair::miller(&r);
87
88    //.. or alternatively
89    //    let mut v = pair::ate2(&g, &d, &pk, &hm);
90
91    v = pair::fexp(&v);
92    if v.isunity() {
93        return BLS_OK;
94    }
95    return BLS_FAIL;
96}