Botan 3.11.1
Crypto and TLS for C&
Botan::Dilithium_Algos Namespace Reference

Functions

std::pair< DilithiumSeedRho, DilithiumPolyVecdecode_public_key (StrongSpan< const DilithiumSerializedPublicKey > pk, const DilithiumConstants &mode)
std::optional< std::tuple< DilithiumCommitmentHash, DilithiumPolyVec, DilithiumPolyVec > > decode_signature (StrongSpan< const DilithiumSerializedSignature > sig, const DilithiumConstants &mode)
std::pair< DilithiumPolyVec, DilithiumPolyVecdecompose (const DilithiumPolyVec &vec, const DilithiumConstants &mode)
DilithiumSerializedCommitment encode_commitment (const DilithiumPolyVec &w1, const DilithiumConstants &mode)
DilithiumSerializedPublicKey encode_public_key (StrongSpan< const DilithiumSeedRho > rho, const DilithiumPolyVec &t1, const DilithiumConstants &mode)
DilithiumSerializedSignature encode_signature (StrongSpan< const DilithiumCommitmentHash > c, const DilithiumPolyVec &response, const DilithiumPolyVec &hint, const DilithiumConstants &mode)
DilithiumPolyMatNTT expand_A (StrongSpan< const DilithiumSeedRho > rho, const DilithiumConstants &mode)
DilithiumInternalKeypair expand_keypair (DilithiumSeedRandomness xi, DilithiumConstants mode)
DilithiumPolyVec expand_mask (StrongSpan< const DilithiumSeedRhoPrime > rhoprime, uint16_t nonce, const DilithiumConstants &mode)
std::pair< DilithiumPolyVec, DilithiumPolyVecexpand_s (StrongSpan< const DilithiumSeedRhoPrime > rhoprime, const DilithiumConstants &mode)
bool infinity_norm_within_bound (const DilithiumPolyVec &vec, size_t bound)
DilithiumPolyVec make_hint (const DilithiumPolyVec &z, const DilithiumPolyVec &r, const DilithiumConstants &mode)
std::pair< DilithiumPolyVec, DilithiumPolyVecpower2round (const DilithiumPolyVec &vec)
DilithiumPoly sample_in_ball (StrongSpan< const DilithiumCommitmentHash > seed, const DilithiumConstants &mode)
void use_hint (DilithiumPolyVec &vec, const DilithiumPolyVec &hints, const DilithiumConstants &mode)

Function Documentation

◆ decode_public_key()

std::pair< DilithiumSeedRho, DilithiumPolyVec > Botan::Dilithium_Algos::decode_public_key ( StrongSpan< const DilithiumSerializedPublicKey > pk,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 23 (pkDecode)

Definition at line 348 of file dilithium_algos.cpp.

349 {
350 if(pk.size() != mode.public_key_bytes()) {
351 throw Decoding_Error("Dilithium: Invalid public key length");
352 }
353
354 BufferSlicer slicer(pk);
356
357 DilithiumPolyVec t1(mode.k());
358 for(auto& p : t1) {
359 poly_unpack_t1(p, slicer);
360 }
361 BOTAN_ASSERT_NOMSG(slicer.empty());
362
363 return {std::move(rho), std::move(t1)};
364}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
size_t public_key_bytes() const
byte length of the encoded public key
uint8_t k() const
dimensions of the expanded matrix A
static constexpr size_t SEED_RHO_BYTES
decltype(auto) size() const noexcept(noexcept(this->m_span.size()))
Botan::CRYSTALS::PolynomialVector< DilithiumPolyTraits, Botan::CRYSTALS::Domain::Normal > DilithiumPolyVec
Strong< std::vector< uint8_t >, struct DilithiumPublicSeed_ > DilithiumSeedRho
Public seed to sample the polynomial matrix A from.
BOTAN_FORCE_INLINE constexpr T rho(T x)
Definition rotate.h:53

References BOTAN_ASSERT_NOMSG, Botan::BufferSlicer::copy(), Botan::BufferSlicer::empty(), Botan::DilithiumConstants::k(), Botan::DilithiumConstants::public_key_bytes(), Botan::rho(), Botan::DilithiumConstants::SEED_RHO_BYTES, and Botan::StrongSpan< T >::size().

Referenced by Botan::Dilithium_PublicKeyInternal::decode().

◆ decode_signature()

std::optional< std::tuple< DilithiumCommitmentHash, DilithiumPolyVec, DilithiumPolyVec > > Botan::Dilithium_Algos::decode_signature ( StrongSpan< const DilithiumSerializedSignature > sig,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 27 (sigDecode)

Definition at line 496 of file dilithium_algos.cpp.

497 {
498 BufferSlicer slicer(sig);
499 BOTAN_ASSERT_NOMSG(slicer.remaining() == mode.signature_bytes());
500
501 auto commitment_hash = slicer.copy<DilithiumCommitmentHash>(mode.commitment_hash_full_bytes());
502
503 DilithiumPolyVec response(mode.l());
504 for(auto& p : response) {
505 poly_unpack_gamma1(p, slicer, mode);
506 }
507 BOTAN_ASSERT_NOMSG(slicer.remaining() == size_t(mode.omega()) + mode.k());
508
509 auto hint = hint_unpack(slicer, mode);
510 BOTAN_ASSERT_NOMSG(slicer.empty());
511 if(!hint.has_value()) {
512 return std::nullopt;
513 }
514
515 return std::make_tuple(std::move(commitment_hash), std::move(response), std::move(hint.value()));
516}
size_t commitment_hash_full_bytes() const
length of the entire commitment hash 'c~' in bytes (differs between R3 and ML-DSA)
size_t signature_bytes() const
byte length of the encoded signature
uint8_t l() const
dimensions of the expanded matrix A
DilithiumOmega omega() const
maximal hamming weight of the hint polynomial vector 'h'
Strong< std::vector< uint8_t >, struct DilithiumCommitmentHash_ > DilithiumCommitmentHash
Hash of the message representative and the signer's commitment.

References BOTAN_ASSERT_NOMSG, Botan::DilithiumConstants::commitment_hash_full_bytes(), Botan::BufferSlicer::copy(), Botan::BufferSlicer::empty(), Botan::DilithiumConstants::k(), Botan::DilithiumConstants::l(), Botan::DilithiumConstants::omega(), Botan::BufferSlicer::remaining(), and Botan::DilithiumConstants::signature_bytes().

◆ decompose()

std::pair< DilithiumPolyVec, DilithiumPolyVec > Botan::Dilithium_Algos::decompose ( const DilithiumPolyVec & vec,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 36 (Decompose) on a polynomial vector

Algorithms 37 (HighBits) and 38 (LowBits) are not implemented explicitly, simply use the first (HighBits) and second (LowBits) element of the result.

Definition at line 825 of file dilithium_algos.cpp.

825 {
827 switch(mode.gamma2()) {
828 case Gamma2::Qminus1DividedBy32:
829 return decompose_all_coefficients<Gamma2::Qminus1DividedBy32>(vec);
830 break;
831 case Gamma2::Qminus1DividedBy88:
832 return decompose_all_coefficients<Gamma2::Qminus1DividedBy88>(vec);
833 break;
834 }
835
837}
#define BOTAN_ASSERT_UNREACHABLE()
Definition assert.h:163
DilithiumGamma2 gamma2() const
low-order rounding range for decomposing the commitment from polynomial vector 'w'

References BOTAN_ASSERT_UNREACHABLE, and Botan::DilithiumConstants::gamma2().

◆ encode_commitment()

DilithiumSerializedCommitment Botan::Dilithium_Algos::encode_commitment ( const DilithiumPolyVec & w1,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 28 (w1Encode)

Definition at line 521 of file dilithium_algos.cpp.

521 {
523 BufferStuffer stuffer(commitment);
524
525 for(const auto& p : w1) {
526 poly_pack_w1(p, stuffer, mode);
527 }
528
529 return commitment;
530}
Helper class to ease in-place marshalling of concatenated fixed-length values.
size_t serialized_commitment_bytes() const
byte length of the packed commitment polynomial vector 'w1'
Strong< std::vector< uint8_t >, struct DilithiumSerializedCommitment_ > DilithiumSerializedCommitment
Serialized representation of a commitment w1.

References Botan::DilithiumConstants::serialized_commitment_bytes().

◆ encode_public_key()

DilithiumSerializedPublicKey Botan::Dilithium_Algos::encode_public_key ( StrongSpan< const DilithiumSeedRho > rho,
const DilithiumPolyVec & t1,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 22 (pkEncode)

Definition at line 330 of file dilithium_algos.cpp.

332 {
334 BufferStuffer stuffer(pk);
335
336 stuffer.append(rho);
337 for(const auto& p : t1) {
338 poly_pack_t1(p, stuffer);
339 }
340
341 BOTAN_ASSERT_NOMSG(stuffer.full());
342 return pk;
343}
Strong< std::vector< uint8_t >, struct DilithiumSerializedPublicKey_ > DilithiumSerializedPublicKey
Serialized public key data (result of pkEncode(pk)).

References Botan::BufferStuffer::append(), BOTAN_ASSERT_NOMSG, Botan::BufferStuffer::full(), Botan::DilithiumConstants::public_key_bytes(), and Botan::rho().

Referenced by Botan::Dilithium_PublicKeyInternal::raw_pk().

◆ encode_signature()

DilithiumSerializedSignature Botan::Dilithium_Algos::encode_signature ( StrongSpan< const DilithiumCommitmentHash > c,
const DilithiumPolyVec & response,
const DilithiumPolyVec & hint,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 26 (sigEncode)

Definition at line 477 of file dilithium_algos.cpp.

480 {
482 BufferStuffer stuffer(sig);
483
484 stuffer.append(c);
485 for(const auto& p : response) {
486 poly_pack_gamma1(p, stuffer, mode);
487 }
488 hint_pack(hint, stuffer, mode);
489
490 return sig;
491}
Strong< std::vector< uint8_t >, struct DilithiumSerializedSignature_ > DilithiumSerializedSignature
Serialized signature data.

References Botan::BufferStuffer::append(), and Botan::DilithiumConstants::signature_bytes().

◆ expand_A()

DilithiumPolyMatNTT Botan::Dilithium_Algos::expand_A ( StrongSpan< const DilithiumSeedRho > rho,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 32 (ExpandA)

Note that the actual concatenation of rho, s and r is done downstream in the sampling function.

Definition at line 701 of file dilithium_algos.cpp.

701 {
702 DilithiumPolyMatNTT A(mode.k(), mode.l());
703 for(uint8_t r = 0; r < mode.k(); ++r) {
704 for(uint8_t s = 0; s < mode.l(); ++s) {
705 sample_ntt_uniform(rho, A[r][s], load_le(std::array{s, r}), mode);
706 }
707 }
708 return A;
709}
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:495
Botan::CRYSTALS::PolynomialMatrix< DilithiumPolyTraits > DilithiumPolyMatNTT

References Botan::DilithiumConstants::k(), Botan::DilithiumConstants::l(), Botan::load_le(), and Botan::rho().

Referenced by expand_keypair().

◆ expand_keypair()

DilithiumInternalKeypair Botan::Dilithium_Algos::expand_keypair ( DilithiumSeedRandomness xi,
DilithiumConstants mode )

NIST FIPS 204, Algorithm 6 (ML-DSA.KeyGen_internal)

Lines 5-7 are extracted into a separate function, see above. The key encoding is deferred until the user explicitly invokes the encoding.

Definition at line 668 of file dilithium_algos.cpp.

668 {
670 throw Decoding_Error("Invalid ML-DSA seed size");
671 }
672 const auto& sympriv = mode.symmetric_primitives();
673 CT::poison(xi);
674
675 auto [rho, rhoprime, K] = sympriv.H(xi);
676 CT::unpoison(rho); // rho is public (seed for the public matrix A)
677
678 const auto A = Dilithium_Algos::expand_A(rho, mode);
679 auto [s1, s2] = Dilithium_Algos::expand_s(rhoprime, mode);
680 auto [t1, t0] = Dilithium_Algos::compute_t1_and_t0(A, s1, s2);
681
682 CT::unpoison(t1); // part of the public key
683
685 std::make_shared<Dilithium_PublicKeyInternal>(mode, std::move(rho), std::move(t1)),
686 std::make_shared<Dilithium_PrivateKeyInternal>(
687 std::move(mode), std::move(xi), std::move(K), std::move(s1), std::move(s2), std::move(t0)),
688 };
689
690 CT::unpoison(*keypair.second);
691
692 return keypair;
693}
Dilithium_Symmetric_Primitives_Base & symmetric_primitives() const
static constexpr size_t SEED_RANDOMNESS_BYTES
size_type size() const noexcept(noexcept(this->get().size()))
constexpr void unpoison(const T *p, size_t n)
Definition ct_utils.h:67
constexpr void poison(const T *p, size_t n)
Definition ct_utils.h:56
DilithiumPolyMatNTT expand_A(StrongSpan< const DilithiumSeedRho > rho, const DilithiumConstants &mode)
std::pair< DilithiumPolyVec, DilithiumPolyVec > expand_s(StrongSpan< const DilithiumSeedRhoPrime > rhoprime, const DilithiumConstants &mode)
std::pair< std::shared_ptr< Dilithium_PublicKeyInternal >, std::shared_ptr< Dilithium_PrivateKeyInternal > > DilithiumInternalKeypair
Internal representation of a Dilithium key pair.

References expand_A(), expand_s(), Botan::CT::poison(), Botan::rho(), Botan::DilithiumConstants::SEED_RANDOMNESS_BYTES, Botan::detail::Container_Strong_Adapter_Base< T >::size(), Botan::DilithiumConstants::symmetric_primitives(), and Botan::CT::unpoison().

Referenced by Botan::ML_DSA_Expanding_Keypair_Codec::decode_keypair(), and Botan::Dilithium_PrivateKey::Dilithium_PrivateKey().

◆ expand_mask()

DilithiumPolyVec Botan::Dilithium_Algos::expand_mask ( StrongSpan< const DilithiumSeedRhoPrime > rhoprime,
uint16_t nonce,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 34 (ExpandMask)

Definition at line 734 of file dilithium_algos.cpp.

736 {
737 DilithiumPolyVec s(mode.l());
738 for(auto& p : s) {
739 auto xof = mode.symmetric_primitives().H(rhoprime, nonce++);
740 poly_unpack_gamma1(p, *xof, mode);
741 }
742 return s;
743}
DilithiumHashedPublicKey H(StrongSpan< const DilithiumSerializedPublicKey > pk) const

References Botan::Dilithium_Symmetric_Primitives_Base::H(), Botan::DilithiumConstants::l(), and Botan::DilithiumConstants::symmetric_primitives().

◆ expand_s()

std::pair< DilithiumPolyVec, DilithiumPolyVec > Botan::Dilithium_Algos::expand_s ( StrongSpan< const DilithiumSeedRhoPrime > rhoprime,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 33 (ExpandS)

Definition at line 714 of file dilithium_algos.cpp.

715 {
716 auto result = std::make_pair(DilithiumPolyVec(mode.l()), DilithiumPolyVec(mode.k()));
717 auto& [s1, s2] = result;
718
719 uint16_t nonce = 0;
720 for(auto& p : s1) {
721 sample_uniform_eta(rhoprime, p, nonce++, mode);
722 }
723
724 for(auto& p : s2) {
725 sample_uniform_eta(rhoprime, p, nonce++, mode);
726 }
727
728 return result;
729}

References Botan::DilithiumConstants::k(), and Botan::DilithiumConstants::l().

Referenced by expand_keypair().

◆ infinity_norm_within_bound()

bool Botan::Dilithium_Algos::infinity_norm_within_bound ( const DilithiumPolyVec & vec,
size_t bound )

Definition at line 942 of file dilithium_algos.cpp.

942 {
943 BOTAN_DEBUG_ASSERT(bound <= (DilithiumConstants::Q - 1) / 8);
944
945 // It is ok to leak which coefficient violates the bound as the probability
946 // for each coefficient is independent of secret data but we must not leak
947 // the sign of the centralized representative.
948 for(const auto& p : vec) {
949 for(auto c : p) {
950 const auto abs_c = c - is_negative_mask(c).if_set_return(2 * c);
951 if(CT::driveby_unpoison(abs_c >= bound)) {
952 return false;
953 }
954 }
955 }
956
957 return true;
958}
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:129
static constexpr T Q
modulus
decltype(auto) driveby_unpoison(T &&v)
Definition ct_utils.h:243

References BOTAN_DEBUG_ASSERT, Botan::CT::driveby_unpoison(), and Botan::DilithiumConstants::Q.

◆ make_hint()

DilithiumPolyVec Botan::Dilithium_Algos::make_hint ( const DilithiumPolyVec & z,
const DilithiumPolyVec & r,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 39 (MakeHint)

MakeHint is specified per value in FIPS 204. This implements the algorithm for the entire polynomial vector. The specified algorithm is equivalent to the inner lambda.

TODO: This is taken from the reference implementation. We should implement it as specified in the spec, and see if that has any performance impact.

Definition at line 849 of file dilithium_algos.cpp.

849 {
850 BOTAN_DEBUG_ASSERT(z.size() == r.size());
851
852 auto make_hint = [gamma2 = uint32_t(mode.gamma2()),
853 q_gamma2 = static_cast<uint32_t>(DilithiumConstants::Q) - uint32_t(mode.gamma2())](
854 int32_t c0, int32_t c1) -> CT::Choice {
855 BOTAN_DEBUG_ASSERT(c0 >= 0);
856 BOTAN_DEBUG_ASSERT(c1 >= 0);
857
858 const uint32_t pc0 = static_cast<uint32_t>(c0);
859 const uint32_t pc1 = static_cast<uint32_t>(c1);
860
861 return (CT::Mask<uint32_t>::is_gt(pc0, gamma2) & CT::Mask<uint32_t>::is_lte(pc0, q_gamma2) &
863 .as_choice();
864 };
865
866 DilithiumPolyVec hint(r.size());
867
868 for(size_t i = 0; i < r.size(); ++i) {
869 for(size_t j = 0; j < r[i].size(); ++j) {
870 hint[i][j] = static_cast<int>(make_hint(z[i][j], r[i][j]).as_bool());
871 }
872 }
873
874 BOTAN_DEBUG_ASSERT(hint.ct_validate_value_range(0, 1));
875
876 return hint;
877}
static constexpr Mask< T > is_lte(T x, T y)
Definition ct_utils.h:463
static constexpr Mask< T > is_equal(T x, T y)
Definition ct_utils.h:442
static constexpr Mask< T > is_gt(T x, T y)
Definition ct_utils.h:458
static constexpr Mask< T > is_zero(T x)
Definition ct_utils.h:437
DilithiumPolyVec make_hint(const DilithiumPolyVec &z, const DilithiumPolyVec &r, const DilithiumConstants &mode)

References BOTAN_DEBUG_ASSERT, Botan::CRYSTALS::PolynomialVector< Trait, D >::ct_validate_value_range(), Botan::DilithiumConstants::gamma2(), Botan::CT::Mask< T >::is_equal(), Botan::CT::Mask< T >::is_gt(), Botan::CT::Mask< T >::is_lte(), Botan::CT::Mask< T >::is_zero(), make_hint(), Botan::DilithiumConstants::Q, and Botan::CRYSTALS::PolynomialVector< Trait, D >::size().

Referenced by make_hint().

◆ power2round()

std::pair< DilithiumPolyVec, DilithiumPolyVec > Botan::Dilithium_Algos::power2round ( const DilithiumPolyVec & vec)

NIST FIPS 204, Algorithm 35 (Power2Round)

In contrast to the spec, this function takes a polynomial vector and performs the power2round operation on each coefficient in the vector. The actual Algorithm 35 as specified is actually just the inner lambda.

Definition at line 752 of file dilithium_algos.cpp.

752 {
753 // This procedure is taken verbatim from Dilithium's reference implementation.
754 auto power2round = [d = DilithiumConstants::D](int32_t r) -> std::pair<int32_t, int32_t> {
755 const int32_t r1 = (r + (1 << (d - 1)) - 1) >> d;
756 const int32_t r0 = r - (r1 << d);
757 return {r1, r0};
758 };
759
760 auto result = std::make_pair(DilithiumPolyVec(vec.size()), DilithiumPolyVec(vec.size()));
761
762 for(size_t i = 0; i < vec.size(); ++i) {
763 for(size_t j = 0; j < vec[i].size(); ++j) {
764 std::tie(result.first[i][j], result.second[i][j]) = power2round(vec[i][j]);
765 }
766 }
767
768 return result;
769}
static constexpr T D
number of dropped bits from t (see FIPS 204 Section 5)
std::pair< DilithiumPolyVec, DilithiumPolyVec > power2round(const DilithiumPolyVec &vec)

References Botan::DilithiumConstants::D, power2round(), and Botan::CRYSTALS::PolynomialVector< Trait, D >::size().

Referenced by power2round().

◆ sample_in_ball()

DilithiumPoly Botan::Dilithium_Algos::sample_in_ball ( StrongSpan< const DilithiumCommitmentHash > seed,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 29 (SampleInBall)

Definition at line 535 of file dilithium_algos.cpp.

535 {
536 // This generator resembles the while loop in the spec.
537 auto xof = mode.symmetric_primitives().H(seed);
539
541 uint64_t signs = load_le(bounded_xof.next<8>());
542 for(size_t i = c.size() - mode.tau(); i < c.size(); ++i) {
543 const auto j = bounded_xof.next_byte([i](uint8_t byte) { return byte <= i; });
544 c[i] = c[j];
545 c[j] = 1 - 2 * (signs & 1);
546 signs >>= 1;
547 }
548
551
552 return c;
553}
constexpr size_t hamming_weight() const noexcept
Definition pqcrystals.h:294
constexpr size_t size() const
Definition pqcrystals.h:276
constexpr bool ct_validate_value_range(T min, T max) const noexcept
Definition pqcrystals.h:289
DilithiumTau tau() const
hamming weight of the polynomial 'c' sampled from the commitment's hash
detail::Bounded_XOF< XOF &, bound > Bounded_XOF
Botan::CRYSTALS::Polynomial< DilithiumPolyTraits, Botan::CRYSTALS::Domain::Normal > DilithiumPoly

References BOTAN_DEBUG_ASSERT, Botan::CRYSTALS::Polynomial< Trait, D >::ct_validate_value_range(), Botan::Dilithium_Symmetric_Primitives_Base::H(), Botan::CRYSTALS::Polynomial< Trait, D >::hamming_weight(), Botan::load_le(), Botan::CRYSTALS::Polynomial< Trait, D >::size(), Botan::DilithiumConstants::symmetric_primitives(), and Botan::DilithiumConstants::tau().

◆ use_hint()

void Botan::Dilithium_Algos::use_hint ( DilithiumPolyVec & vec,
const DilithiumPolyVec & hints,
const DilithiumConstants & mode )

NIST FIPS 204, Algorithm 40 (UseHint)

UseHint is specified per value in FIPS 204. This implements the algorithm for the entire polynomial vector. The specified algorithm is equivalent to the inner lambdas of 'use_hint_with_coefficients'.

Definition at line 924 of file dilithium_algos.cpp.

924 {
925 BOTAN_DEBUG_ASSERT(hints.size() == vec.size());
928
930 switch(mode.gamma2()) {
931 case Gamma2::Qminus1DividedBy32:
932 use_hint_on_coefficients<Gamma2::Qminus1DividedBy32>(hints, vec);
933 break;
934 case Gamma2::Qminus1DividedBy88:
935 use_hint_on_coefficients<Gamma2::Qminus1DividedBy88>(hints, vec);
936 break;
937 }
938
940}
constexpr bool ct_validate_value_range(T min, T max) const noexcept
Definition pqcrystals.h:439

References BOTAN_DEBUG_ASSERT, Botan::CRYSTALS::PolynomialVector< Trait, D >::ct_validate_value_range(), Botan::DilithiumConstants::gamma2(), Botan::DilithiumConstants::Q, and Botan::CRYSTALS::PolynomialVector< Trait, D >::size().