pub fn dec_chunks(
    dks: &SecretKey,
    i: usize,
    crsz: &Crsz,
    tau: &[Bit],
    associated_data: &[u8],
) -> Result<Vec<isize>, DecErr> {
    let extended_tau = extend_tau(&crsz.cc, &crsz.rr, &crsz.ss, tau, associated_data);
    let dk = match find_prefix(dks, tau) {
        None => return Err(DecErr::ExpiredKey),
        Some(node) => node,
    };
    let mut bneg = dk.b.clone();
    let mut l = dk.tau.len();
    for tmp in dk.d_t.iter() {
        if extended_tau[l] == Bit::One {
            bneg.add(tmp);
        }
        l += 1
    }
    for k in 0..LAMBDA_H {
        if extended_tau[LAMBDA_T + k] == Bit::One {
            bneg.add(&dk.d_h[k]);
        }
    }
    bneg.neg();
    let g1 = ECP::generator();
    let g2 = ECP2::generator();
    let mut eneg = dk.e.clone();
    eneg.neg();
    let cj = &crsz.cc[i];
    use miracl_core::bls12381::pair;

    // zipWith4 f cj rr ss zz where
    //   f c spec_r s z =
    //     ate(g2, c) * ate(bneg, spec_r) * ate(z, dk_a) * ate(eneg, s)
    let powers: Vec<_> = cj
        .iter()
        .zip(crsz.rr.iter().zip(crsz.ss.iter().zip(crsz.zz.iter())))
        .map(|(c, (spec_r, (s, z)))| {
            let mut m = pair::ate2(&g2, c, &bneg, spec_r);
            m.mul(&pair::ate2(z, &dk.a, &eneg, s));
            pair::fexp(&m)
        })
        .collect();

    // Find discrete log of powers with baby-step-giant-step.
    let base = pair::fexp(&pair::ate(&g2, &g1));
    let mut dlogs = Vec::new();
    let spec_n = crsz.cc.len();
    let spec_m = crsz.cc[0].len();
    for item in powers.iter() {
        match baby_giant(item, &base, 0, CHUNK_SIZE) {
            // Happy path: honest DKG participants.
            Some(dlog) => dlogs.push(BIG::new_int(dlog)),
            // It may take hours to brute force a cheater's discrete log.
            None => match solve_cheater_log(spec_n, spec_m, item) {
                Some(big) => dlogs.push(big),
                None => panic!("Unsolvable discrete log!"),
            },
        }
    }

    // Clippy dislikes `FrBytes::SIZE` or `MESSAGE_BYTES` instead of `32`.
    let mut fr_bytes = [0u8; 32];
    let mut big_bytes = [0u8; 48];
    let b = BIG::new_int(CHUNK_SIZE);
    let mut acc = BIG::new_int(0);
    let r = BIG::new_ints(&rom::CURVE_ORDER);
    for src in dlogs.iter() {
        acc = BIG::modadd(src, &BIG::modmul(&acc, &b, &r), &r);
    }
    acc.tobytes(&mut big_bytes);
    fr_bytes[..].clone_from_slice(&big_bytes[16..(32 + 16)]);

    // Break up fr_bytes into a vec of isize, which will be combined again later.
    // It may be better to simply return FrBytes and change enc_chunks() to take
    // FrBytes and have it break it into chunks. This would confine the chunking
    // logic to the DKG, where it belongs.
    // (I tried this for a while, but it seemed to touch a lot of code.)
    let redundant = fr_bytes[..]
        .chunks_exact(CHUNK_BYTES)
        .map(|x| 256 * (x[0] as isize) + (x[1] as isize))
        .collect();
    Ok(redundant)
}
/// Decrypt the i-th group of chunks.
///
/// Decrypting a message for a future epoch hardly costs more than a message for
/// a current epoch: at most lambda_t point additions.
///
/// Upgrading a key is expensive in comparison because we must compute new
/// subtree roots and re-"blind" them (the random deltas of the paper) to hide
/// ciphertexts from future keys. Each re-blinding costs at least lambda_h
/// (which is 256 in our system) point multiplications.
///
/// Caller must ensure i < n, where n = crsz.cc.len().
Decrypt the i-th group of chunks.
Decrypting a message for a future epoch hardly costs more than a message for
a current epoch: at most lambda_t point additions.

Upgrading a key is expensive in comparison because we must compute new
subtree roots and re-"blind" them (the random deltas of the paper) to hide
ciphertexts from future keys. Each re-blinding costs at least lambda_h
(which is 256 in our system) point multiplications.

Caller must ensure i < n, where n = crsz.cc.len().
Decrypt the i - th group of chunks . Decrypting a message for a future epoch hardly costs more than a message for a current epoch : at most lambda_t point additions . Upgrading a key is expensive in comparison because we must compute new subtree roots and re - " blind " them ( the random deltas of the paper ) to hide ciphertexts from future keys . Each re - blinding costs at least lambda_h ( which is 256 in our system ) point multiplications . Caller must ensure i < n where n = crsz . cc . len () .
pub fn dec_chunks(
    dks: &SecretKey,
    i: usize,
    crsz: &Crsz,
    tau: &[Bit],
    associated_data: &[u8],
) -> Result<Vec<isize>, DecErr> {
    let extended_tau = extend_tau(&crsz.cc, &crsz.rr, &crsz.ss, tau, associated_data);
    let dk = match find_prefix(dks, tau) {
        None => return Err(DecErr::ExpiredKey),
        Some(node) => node,
    };
    let mut bneg = dk.b.clone();
    let mut l = dk.tau.len();
    for tmp in dk.d_t.iter() {
        if extended_tau[l] == Bit::One {
            bneg.add(tmp);
        }
        l += 1
    }
    for k in 0..LAMBDA_H {
        if extended_tau[LAMBDA_T + k] == Bit::One {
            bneg.add(&dk.d_h[k]);
        }
    }
    bneg.neg();
    let g1 = ECP::generator();
    let g2 = ECP2::generator();
    let mut eneg = dk.e.clone();
    eneg.neg();
    let cj = &crsz.cc[i];
    use miracl_core::bls12381::pair;
    // zipWith4 f cj rr ss zz where
    //   f c spec_r s z =
    //     ate(g2, c) * ate(bneg, spec_r) * ate(z, dk_a) * ate(eneg, s)
    let powers: Vec<_> = cj
        .iter()
        .zip(crsz.rr.iter().zip(crsz.ss.iter().zip(crsz.zz.iter())))
        .map(|(c, (spec_r, (s, z)))| {
            let mut m = pair::ate2(&g2, c, &bneg, spec_r);
            m.mul(&pair::ate2(z, &dk.a, &eneg, s));
            pair::fexp(&m)
        })
        .collect();
    // Find discrete log of powers with baby-step-giant-step.
    let base = pair::fexp(&pair::ate(&g2, &g1));
    let mut dlogs = Vec::new();
    let spec_n = crsz.cc.len();
    let spec_m = crsz.cc[0].len();
    for item in powers.iter() {
        match baby_giant(item, &base, 0, CHUNK_SIZE) {
            // Happy path: honest DKG participants.
            Some(dlog) => dlogs.push(BIG::new_int(dlog)),
            // It may take hours to brute force a cheater's discrete log.
            None => match solve_cheater_log(spec_n, spec_m, item) {
                Some(big) => dlogs.push(big),
                None => panic!("Unsolvable discrete log!"),
            },
        }
    }
    // Clippy dislikes `FrBytes::SIZE` or `MESSAGE_BYTES` instead of `32`.
    let mut fr_bytes = [0u8; 32];
    let mut big_bytes = [0u8; 48];
    let b = BIG::new_int(CHUNK_SIZE);
    let mut acc = BIG::new_int(0);
    let r = BIG::new_ints(&rom::CURVE_ORDER);
    for src in dlogs.iter() {
        acc = BIG::modadd(src, &BIG::modmul(&acc, &b, &r), &r);
    }
    acc.tobytes(&mut big_bytes);
    fr_bytes[..].clone_from_slice(&big_bytes[16..(32 + 16)]);
    // Break up fr_bytes into a vec of isize, which will be combined again later.
    // It may be better to simply return FrBytes and change enc_chunks() to take
    // FrBytes and have it break it into chunks. This would confine the chunking
    // logic to the DKG, where it belongs.
    // (I tried this for a while, but it seemed to touch a lot of code.)
    let redundant = fr_bytes[..]
        .chunks_exact(CHUNK_BYTES)
        .map(|x| 256 * (x[0] as isize) + (x[1] as isize))
        .collect();
    Ok(redundant)
}
pub fn dec_chunks ( dks : & SecretKey , i : usize , crsz : & Crsz , tau : & [ Bit ] , associated_data : & [ u8 ] , ) -> Result < Vec < isize > , DecErr > { let extended_tau = extend_tau ( & crsz . cc , & crsz . rr , & crsz . ss , tau , associated_data ) ; let dk = match find_prefix ( dks , tau ) { None => return Err ( DecErr :: ExpiredKey ) , Some ( node ) => node , } ; let mut bneg = dk . b . clone ( ) ; let mut l = dk . tau . len ( ) ; for tmp in dk . d_t . iter ( ) { if extended_tau [ l ] == Bit :: One { bneg . add ( tmp ) ; } l += 1 } for k in 0 .. LAMBDA_H { if extended_tau [ LAMBDA_T + k ] == Bit :: One { bneg . add ( & dk . d_h [ k ] ) ; } } bneg . neg ( ) ; let g1 = ECP :: generator ( ) ; let g2 = ECP2 :: generator ( ) ; let mut eneg = dk . e . clone ( ) ; eneg . neg ( ) ; let cj = & crsz . cc [ i ] ; use miracl_core :: bls12381 :: pair ; // zipWith4 f cj rr ss zz where //   f c spec_r s z = //     ate(g2, c) * ate(bneg, spec_r) * ate(z, dk_a) * ate(eneg, s) let powers : Vec < _ > = cj . iter ( ) . zip ( crsz . rr . iter ( ) . zip ( crsz . ss . iter ( ) . zip ( crsz . zz . iter ( ) ) ) ) . map ( | ( c , ( spec_r , ( s , z ) ) ) | { let mut m = pair :: ate2 ( & g2 , c , & bneg , spec_r ) ; m . mul ( & pair :: ate2 ( z , & dk . a , & eneg , s ) ) ; pair :: fexp ( & m ) } ) . collect ( ) ; // Find discrete log of powers with baby-step-giant-step. let base = pair :: fexp ( & pair :: ate ( & g2 , & g1 ) ) ; let mut dlogs = Vec :: new ( ) ; let spec_n = crsz . cc . len ( ) ; let spec_m = crsz . cc [ 0 ] . len ( ) ; for item in powers . iter ( ) { match baby_giant ( item , & base , 0 , CHUNK_SIZE ) { // Happy path: honest DKG participants. Some ( dlog ) => dlogs . push ( BIG :: new_int ( dlog ) ) , // It may take hours to brute force a cheater's discrete log. None => match solve_cheater_log ( spec_n , spec_m , item ) { Some ( big ) => dlogs . push ( big ) , None => panic ! ( " " ) , } , } } // Clippy dislikes `FrBytes::SIZE` or `MESSAGE_BYTES` instead of `32`. let mut fr_bytes = [ 0u8 ; 32 ] ; let mut big_bytes = [ 0u8 ; 48 ] ; let b = BIG :: new_int ( CHUNK_SIZE ) ; let mut acc = BIG :: new_int ( 0 ) ; let r = BIG :: new_ints ( & rom :: CURVE_ORDER ) ; for src in dlogs . iter ( ) { acc = BIG :: modadd ( src , & BIG :: modmul ( & acc , & b , & r ) , & r ) ; } acc . tobytes ( & mut big_bytes ) ; fr_bytes [ .. ] . clone_from_slice ( & big_bytes [ 16 .. ( 32 + 16 ) ] ) ; // Break up fr_bytes into a vec of isize, which will be combined again later. // It may be better to simply return FrBytes and change enc_chunks() to take // FrBytes and have it break it into chunks. This would confine the chunking // logic to the DKG, where it belongs. // (I tried this for a while, but it seemed to touch a lot of code.) let redundant = fr_bytes [ .. ] . chunks_exact ( CHUNK_BYTES ) . map ( | x | 256 * ( x [ 0 ] as isize ) + ( x [ 1 ] as isize ) ) . collect ( ) ; Ok ( redundant ) }
Decrypt the i-th group of chunks.
Decrypt the i - th group of chunks .
dks
&SecretKey
i
usize
crsz
&Crsz
tau
&[Bit]
associated_data
&[u8]
dks
&SecretKey
i
usize
crsz
&Crsz
tau
&[Bit]
associated_data
&[u8]