504 {
505
506
507
508
509
510
511
512
513
514 if(shares.size() < m_K)
515 throw Decoding_Error("ZFEC: could not decode, less than K surviving shares");
516
517 std::vector<uint8_t> decoding_matrix(m_K * m_K);
518 std::vector<size_t> indexes(m_K);
519 std::vector<const uint8_t*> sharesv(m_K);
520
521 auto shares_b_iter = shares.begin();
522 auto shares_e_iter = shares.rbegin();
523
524 bool missing_primary_share = false;
525
526 for(size_t i = 0; i != m_K; ++i)
527 {
528 size_t share_id = 0;
529 const uint8_t* share_data = nullptr;
530
531 if(shares_b_iter->first == i)
532 {
533 share_id = shares_b_iter->first;
534 share_data = shares_b_iter->second;
535 ++shares_b_iter;
536 }
537 else
538 {
539
540 share_id = shares_e_iter->first;
541 share_data = shares_e_iter->second;
542 ++shares_e_iter;
543 missing_primary_share = true;
544 }
545
546 if(share_id >= m_N)
547 throw Decoding_Error("ZFEC: invalid share id detected during decode");
548
549
550
551
552
553
554
555
556 if(share_id < m_K)
557 {
558 decoding_matrix[i*(m_K+1)] = 1;
559 output_cb(share_id, share_data, share_size);
560 }
561 else
562 {
563 std::memcpy(&decoding_matrix[i*m_K], &m_enc_matrix[share_id*m_K], m_K);
564 }
565
566 sharesv[i] = share_data;
567 indexes[i] = share_id;
568 }
569
570
571
572 if(!missing_primary_share)
573 {
574 for(size_t i = 0; i != indexes.size(); ++i)
575 {
577 }
578 return;
579 }
580
581 invert_matrix(&decoding_matrix[0], m_K);
582
583 for(size_t i = 0; i != indexes.size(); ++i)
584 {
585 if(indexes[i] >= m_K)
586 {
587 std::vector<uint8_t> buf(share_size);
588 for(size_t col = 0; col != m_K; ++col)
589 {
590 addmul(&buf[0], sharesv[col], decoding_matrix[i*m_K + col], share_size);
591 }
592 output_cb(i, &buf[0], share_size);
593 }
594 }
595 }
#define BOTAN_ASSERT_NOMSG(expr)