Documentation
¶
Overview ¶
Package numct provides constant-time arbitrary-precision arithmetic for cryptographic applications.
See README.md for details.
Index ¶
- Variables
- func LCM(out, a, b *Nat)
- type Int
- func (i *Int) Abs(x *Int)
- func (i *Int) Add(lhs, rhs *Int)
- func (i *Int) AddCap(lhs, rhs *Int, capacity int)
- func (i *Int) And(x, y *Int)
- func (i *Int) AndCap(x, y *Int, capacity int)
- func (i *Int) AnnouncedLen() int
- func (i *Int) Big() *big.Int
- func (i *Int) Bytes() []byte
- func (i *Int) Clone() *Int
- func (i *Int) Compare(rhs *Int) (lt, eq, gt ct.Bool)
- func (i *Int) CondAssign(choice ct.Choice, x *Int)
- func (i *Int) CondNeg(choice ct.Choice)
- func (i *Int) Coprime(rhs *Int) ct.Bool
- func (i *Int) Decrement()
- func (i *Int) Div(remainder, numerator, denominator *Int) ct.Bool
- func (i *Int) DivVarTime(remainder, numerator, denominator *Int) (ok ct.Bool)
- func (i *Int) Double(x *Int)
- func (i *Int) Equal(rhs *Int) ct.Bool
- func (i *Int) EuclideanDiv(remainder *Nat, numerator, denominator *Int) (ok ct.Bool)
- func (i *Int) EuclideanDivVarTime(remainder *Nat, numerator, denominator *Int) (ok ct.Bool)
- func (i *Int) GCD(a, b *Int)
- func (i *Int) HashCode() base.HashCode
- func (i *Int) Increment()
- func (i *Int) Int64() int64
- func (i *Int) Inv(x *Int) (ok ct.Bool)
- func (i *Int) IsEven() ct.Bool
- func (i *Int) IsNegative() ct.Bool
- func (i *Int) IsNonZero() ct.Bool
- func (i *Int) IsOdd() ct.Bool
- func (i *Int) IsOne() ct.Bool
- func (i *Int) IsProbablyPrime() ct.Bool
- func (i *Int) IsUnit() ct.Bool
- func (i *Int) IsZero() ct.Bool
- func (i *Int) Lsh(x *Int, shift uint)
- func (i *Int) LshCap(x *Int, shift uint, capacity int)
- func (i *Int) MarshalCBOR() ([]byte, error)
- func (i *Int) Mul(lhs, rhs *Int)
- func (i *Int) MulCap(lhs, rhs *Int, capacity int)
- func (i *Int) Neg(x *Int)
- func (i *Int) Not(x *Int)
- func (i *Int) NotCap(x *Int, capacity int)
- func (i *Int) Or(x, y *Int)
- func (i *Int) OrCap(x, y *Int, capacity int)
- func (i *Int) Resize(capacity int)
- func (i *Int) Rsh(x *Int, shift uint)
- func (i *Int) RshCap(x *Int, shift uint, capacity int)
- func (i *Int) Select(choice ct.Choice, x0, x1 *Int)
- func (i *Int) Set(v *Int)
- func (i *Int) SetBytes(b []byte) (ok ct.Bool)
- func (i *Int) SetInt64(x int64)
- func (i *Int) SetNat(v *Nat)
- func (i *Int) SetOne()
- func (i *Int) SetRandomRangeLH(lowInclusive, highExclusive *Int, prng io.Reader) error
- func (i *Int) SetTwosComplementBEBytes(b []byte)
- func (i *Int) SetUint64(x uint64)
- func (i *Int) SetZero()
- func (i *Int) Sqrt(x *Int) (ok ct.Bool)
- func (i *Int) Square(x *Int)
- func (i *Int) String() string
- func (i *Int) Sub(lhs, rhs *Int)
- func (i *Int) SubCap(lhs, rhs *Int, capacity int)
- func (i *Int) TrueLen() int
- func (i *Int) TwosComplementBEBytes() []byte
- func (i *Int) Uint64() uint64
- func (i *Int) UnmarshalCBOR(data []byte) error
- func (i *Int) Xor(x, y *Int)
- func (i *Int) XorCap(x, y *Int, capacity int)
- type Modulus
- func (m *Modulus) MarshalCBOR() ([]byte, error)
- func (m *Modulus) ModExp(out, base, exp *Nat)
- func (m *Modulus) ModExpI(out, base *Nat, exp *Int)
- func (m *Modulus) ModInv(out, a *Nat) ct.Bool
- func (m *Modulus) ModMul(out, x, y *Nat)
- func (m *Modulus) ModMultiBaseExp(out, bases []*Nat, exp *Nat)
- func (m *Modulus) Set(v *Modulus)
- func (m *Modulus) SetNat(n *Nat) ct.Bool
- func (m *Modulus) UnmarshalCBOR(data []byte) error
- type ModulusBasic
- func (m *ModulusBasic) Big() *big.Int
- func (m *ModulusBasic) BitLen() int
- func (m *ModulusBasic) Bytes() []byte
- func (m *ModulusBasic) BytesBE() []byte
- func (m *ModulusBasic) HashCode() base.HashCode
- func (m *ModulusBasic) IsInRange(x *Nat) ct.Bool
- func (m *ModulusBasic) IsInRangeSymmetric(x *Int) ct.Bool
- func (m *ModulusBasic) IsUnit(x *Nat) ct.Bool
- func (m *ModulusBasic) Mod(out, x *Nat)
- func (m *ModulusBasic) ModAdd(out, x, y *Nat)
- func (m *ModulusBasic) ModDiv(out, x, y *Nat) ct.Bool
- func (m *ModulusBasic) ModExp(out, b, exp *Nat)
- func (m *ModulusBasic) ModExpI(out, b *Nat, exp *Int)
- func (m *ModulusBasic) ModI(out *Nat, x *Int)
- func (m *ModulusBasic) ModInv(out, x *Nat) ct.Bool
- func (m *ModulusBasic) ModMul(out, x, y *Nat)
- func (m *ModulusBasic) ModMultiBaseExp(out, bases []*Nat, exp *Nat)
- func (m *ModulusBasic) ModNeg(out, x *Nat)
- func (m *ModulusBasic) ModSqrt(out, x *Nat) ct.Bool
- func (m *ModulusBasic) ModSub(out, x, y *Nat)
- func (m *ModulusBasic) ModSymmetric(out *Int, x *Nat)
- func (m *ModulusBasic) Nat() *Nat
- func (m *ModulusBasic) Quo(out, x *Nat)
- func (m *ModulusBasic) Random(prng io.Reader) (*Nat, error)
- func (m *ModulusBasic) Saferith() *saferith.Modulus
- func (m *ModulusBasic) Set(v *ModulusBasic)
- func (m *ModulusBasic) SetNat(n *Nat) ct.Bool
- func (m *ModulusBasic) String() string
- type Nat
- func (n *Nat) Abs(i *Int)
- func (n *Nat) Add(lhs, rhs *Nat)
- func (n *Nat) AddCap(lhs, rhs *Nat, capacity int)
- func (n *Nat) And(x, y *Nat)
- func (n *Nat) AndCap(x, y *Nat, capacity int)
- func (n *Nat) AnnouncedLen() int
- func (n *Nat) Big() *big.Int
- func (n *Nat) Bit(i uint) byte
- func (n *Nat) Byte(i uint) byte
- func (n *Nat) Bytes() []byte
- func (n *Nat) BytesBE() []byte
- func (n *Nat) Clone() *Nat
- func (n *Nat) Compare(rhs *Nat) (lt, eq, gt ct.Bool)
- func (n *Nat) CondAssign(choice ct.Choice, x *Nat)
- func (n *Nat) Coprime(x *Nat) ct.Bool
- func (n *Nat) Decrement()
- func (n *Nat) Div(remainder, numerator, denominator *Nat) ct.Bool
- func (n *Nat) DivVarTime(remainder, numerator, denominator *Nat) ct.Bool
- func (n *Nat) Double(x *Nat)
- func (n *Nat) Equal(rhs *Nat) ct.Bool
- func (n *Nat) EuclideanDiv(r, numerator, denominator *Nat) ct.Bool
- func (n *Nat) EuclideanDivVarTime(remainder, numerator, denominator *Nat) ct.Bool
- func (n *Nat) FillBytes(buf []byte) []byte
- func (n *Nat) GCD(x, y *Nat)
- func (n *Nat) HashCode() base.HashCode
- func (n *Nat) Increment()
- func (n *Nat) IsEven() ct.Bool
- func (n *Nat) IsNonZero() ct.Bool
- func (n *Nat) IsOdd() ct.Bool
- func (n *Nat) IsOne() ct.Bool
- func (n *Nat) IsProbablyPrime() ct.Bool
- func (n *Nat) IsZero() ct.Bool
- func (n *Nat) Lift() *Int
- func (n *Nat) Lsh(x *Nat, shift uint)
- func (n *Nat) LshCap(x *Nat, shift uint, capacity int)
- func (n *Nat) MarshalCBOR() ([]byte, error)
- func (n *Nat) Mul(lhs, rhs *Nat)
- func (n *Nat) MulCap(lhs, rhs *Nat, capacity int)
- func (n *Nat) Not(x *Nat)
- func (n *Nat) NotCap(x *Nat, capacity int)
- func (n *Nat) Or(x, y *Nat)
- func (n *Nat) OrCap(x, y *Nat, capacity int)
- func (n *Nat) Resize(capacity int)
- func (n *Nat) Rsh(x *Nat, shift uint)
- func (n *Nat) RshCap(x *Nat, shift uint, capacity int)
- func (n *Nat) Select(choice ct.Choice, x0, x1 *Nat)
- func (n *Nat) Set(v *Nat)
- func (n *Nat) SetBytes(data []byte) (ok ct.Bool)
- func (n *Nat) SetOne()
- func (n *Nat) SetRandomRangeH(highExclusive *Nat, prng io.Reader) error
- func (n *Nat) SetRandomRangeLH(lowInclusive, highExclusive *Nat, prng io.Reader) error
- func (n *Nat) SetUint64(x uint64)
- func (n *Nat) SetZero()
- func (n *Nat) Sqrt(x *Nat) (ok ct.Bool)
- func (n *Nat) String() string
- func (n *Nat) SubCap(lhs, rhs *Nat, capacity int)
- func (n *Nat) TrueLen() int
- func (n *Nat) Uint64() uint64
- func (n *Nat) UnmarshalCBOR(data []byte) error
- func (n *Nat) Xor(x, y *Nat)
- func (n *Nat) XorCap(x, y *Nat, capacity int)
Constants ¶
This section is empty.
Variables ¶
var (
ErrFailed = errs.New("failed")
)
var ErrInvalidArgument = errs.New("invalid argument")
Functions ¶
Types ¶
type Int ¶
func NewIntFromBig ¶
NewIntFromBig creates a new Int from a big.Int with the given capacity.
func NewIntFromBytes ¶
NewIntFromBytes creates a new Int from a big-endian byte slice.
func NewIntFromSaferith ¶
NewIntFromSaferith creates a new Int from a saferith.Int.
func NewIntFromUint64 ¶
NewIntFromUint64 creates a new Int set to the given uint64 value.
func (*Int) AddCap ¶
AddCap sets i = lhs + rhs with capacity capacity. When capacity < 0, it is set to max(lhs.AnnouncedLen(), rhs.AnnouncedLen()) + 1.
func (*Int) And ¶
And sets i = x & y. For signed integers, this operates on the two's complement representation.
func (*Int) AndCap ¶
AndCap sets i = x & y with capacity capacity. For signed integers, this operates on the two's-complement representation.
func (*Int) AnnouncedLen ¶
AnnouncedLen returns the announced length in bits of i. Safe to be used publicly.
func (*Int) Bytes ¶
Bytes returns a sign-magnitude encoding:
b[0] = 0 if i >= 0, 1 if i < 0 b[1:] = big-endian |i|
func (*Int) CondAssign ¶
CondAssign sets i = x iff choice == 1, otherwise leaves i unchanged.
func (*Int) Div ¶
Div sets n = numerator / denominator. If r is not nil, it will be set it to the remainder. It returns ok=1 if the division was successful, ok=0 otherwise (i.e., division by zero). The number of bits of the quotient will be numerator.AnnouncedLen() and the number of bits of the remainder will be denominator.AnnouncedLen().
func (*Int) DivVarTime ¶
DivVarTime sets n to quotient of numerator / denominator. If r is not nil, it will be set it to the remainder. It returns ok=1 if the division was successful, ok=0 otherwise (i.e., division by zero). The number of bits of the quotient will be min(numerator.AnnouncedLen(), numerator.AnnouncedLen() - denominator.TrueLen() + 2) and the number of bits of the remainder will be denominator.AnnouncedLen().
func (*Int) EuclideanDiv ¶
EuclideanDiv sets n to quotient of numerator / denominator. If r is not nil, it will be set it to the remainder. It returns ok=1 if the division was successful, ok=0 otherwise (i.e., division by zero). The number of bits of the quotient will be numerator.AnnouncedLen() and the number of bits of the remainder will be denominator.AnnouncedLen().
func (*Int) EuclideanDivVarTime ¶
EuclideanDivVarTime sets n to quotient of numerator / denominator. If r is not nil, it will be set it to the remainder. It returns ok=1 if the division was successful, ok=0 otherwise (i.e., division by zero). The number of bits of the quotient will be min(numerator.AnnouncedLen(), numerator.AnnouncedLen() - denominator.TrueLen() + 2) and the number of bits of the remainder will be denominator.AnnouncedLen().
func (*Int) GCD ¶
GCD sets i = gcd(a, b) in Z, always non-negative. It is implemented via the constant-time Nat.GCD on |a| and |b|.
func (*Int) IsProbablyPrime ¶
IsProbablyPrime returns 1 if i is probably prime and non-negative.
func (*Int) MarshalCBOR ¶
func (*Int) MulCap ¶
MulCap sets i = lhs * rhs with capacity capacity. When capacity < 0, it is set to lhs.AnnouncedLen() + rhs.AnnouncedLen().
func (*Int) Not ¶
Not sets i = ^x. For signed integers, this is equivalent to -(x+1) due to two's complement.
func (*Int) NotCap ¶
NotCap sets i = ^x with a given capacity. For signed integers, this is equivalent to -(x+1) due to two's complement.
func (*Int) Or ¶
Or sets i = x | y. For signed integers, this operates on the two's complement representation.
func (*Int) Resize ¶
Resize resizes i to have the given capacity. When capacity < 0, use the current announced length When capacity >= 0, use the provided capacity.
func (*Int) RshCap ¶
RshCap sets i = x >> shift with given capacity. if capacity < 0, capacity will be x.AnnouncedLen() - shift.
func (*Int) Select ¶
Select sets i = x0 if choice == 0, or i = x1 if choice == 1, using only arithmetic on Int (no ct slice helpers).
func (*Int) SetBytes ¶
SetBytes expects the sign-magnitude encoding produced by Bytes/BytesBE:
b[0] = 0 for >=0, 1 for <0 b[1:] = big-endian |i|
Returns ok = 0 only for obviously malformed input (empty slice).
func (*Int) SetRandomRangeLH ¶
SetRandomRangeLH sets i to a random integer in [lowInclusive, highExclusive).
func (*Int) SetTwosComplementBEBytes ¶
SetTwosComplementBEBytes sets i from the two's-complement big-endian byte representation.
func (*Int) Sqrt ¶
Sqrt sets i = sqrt(x) if x is a perfect square, else leaves i unchanged. Returns ok = 1 if x is a perfect square.
func (*Int) SubCap ¶
SubCap sets i = lhs - rhs with capacity capacity. When capacity < 0, it is set to max(lhs.AnnouncedLen(), rhs.AnnouncedLen()) + 1.
func (*Int) TwosComplementBEBytes ¶
TwosComplementBEBytes returns the two's-complement big-endian byte representation of i.
func (*Int) UnmarshalCBOR ¶
type Modulus ¶
type Modulus struct {
*ModulusBasic
// contains filtered or unexported fields
}
Modulus is a modulus implementation based on BoringSSL's BigNum and saferith.Modulus.
func NewModulus ¶
NewModulus creates a new Modulus from a Nat. It returns ok = false if m is zero. Remarks: it leaks the true length of m.
func NewModulusFromBytesBE ¶
NewModulus creates a new Modulus from a Nat.
func (*Modulus) MarshalCBOR ¶
func (*Modulus) ModMultiBaseExp ¶
ModMultiBaseExp sets out[i] = bases[i]^exp (mod m) for all i.
func (*Modulus) UnmarshalCBOR ¶
type ModulusBasic ¶
ModulusBasic is a modulus implementation based on saferith.Modulus.
func (*ModulusBasic) Big ¶
func (m *ModulusBasic) Big() *big.Int
Big returns the big.Int representation of the modulus.
func (*ModulusBasic) BitLen ¶
func (m *ModulusBasic) BitLen() int
BitLen returns the bit length of the modulus.
func (*ModulusBasic) Bytes ¶
func (m *ModulusBasic) Bytes() []byte
Bytes returns the big-endian byte representation of the modulus.
func (*ModulusBasic) BytesBE ¶
func (m *ModulusBasic) BytesBE() []byte
BytesBE returns the big-endian byte representation of the modulus.
func (*ModulusBasic) HashCode ¶
func (m *ModulusBasic) HashCode() base.HashCode
HashCode returns a hash code for the modulus.
func (*ModulusBasic) IsInRange ¶
func (m *ModulusBasic) IsInRange(x *Nat) ct.Bool
IsInRange returns true if 0 <= x < m.
func (*ModulusBasic) IsInRangeSymmetric ¶
func (m *ModulusBasic) IsInRangeSymmetric(x *Int) ct.Bool
IsInRangeSymmetric returns true if -m/2 <= x < m/2.
func (*ModulusBasic) IsUnit ¶
func (m *ModulusBasic) IsUnit(x *Nat) ct.Bool
IsUnit returns true if x is a unit modulo m.
func (*ModulusBasic) ModAdd ¶
func (m *ModulusBasic) ModAdd(out, x, y *Nat)
ModAdd sets out = (x + y) (mod m).
func (*ModulusBasic) ModDiv ¶
func (m *ModulusBasic) ModDiv(out, x, y *Nat) ct.Bool
ModDiv sets out = x * y^{-1} (mod m).
func (*ModulusBasic) ModExp ¶
func (m *ModulusBasic) ModExp(out, b, exp *Nat)
ModExp sets out = base^exp (mod m).
func (*ModulusBasic) ModExpI ¶
func (m *ModulusBasic) ModExpI(out, b *Nat, exp *Int)
ModExpI sets out = base^exp (mod m) where exp is an Int.
func (*ModulusBasic) ModI ¶
func (m *ModulusBasic) ModI(out *Nat, x *Int)
ModI sets out = x (mod m) where x is an Int.
func (*ModulusBasic) ModInv ¶
func (m *ModulusBasic) ModInv(out, x *Nat) ct.Bool
ModInv sets out = x^{-1} (mod m).
func (*ModulusBasic) ModMul ¶
func (m *ModulusBasic) ModMul(out, x, y *Nat)
ModMul sets out = (x * y) (mod m).
func (*ModulusBasic) ModMultiBaseExp ¶
func (m *ModulusBasic) ModMultiBaseExp(out, bases []*Nat, exp *Nat)
ModMultiBaseExp sets out[i] = bases[i]^exp (mod m) for all i.
func (*ModulusBasic) ModNeg ¶
func (m *ModulusBasic) ModNeg(out, x *Nat)
ModNeg sets out = -x (mod m).
func (*ModulusBasic) ModSqrt ¶
func (m *ModulusBasic) ModSqrt(out, x *Nat) ct.Bool
ModSqrt sets out = sqrt(x) (mod m) if it exists.
func (*ModulusBasic) ModSub ¶
func (m *ModulusBasic) ModSub(out, x, y *Nat)
ModSub sets out = (x - y) (mod m).
func (*ModulusBasic) ModSymmetric ¶
func (m *ModulusBasic) ModSymmetric(out *Int, x *Nat)
ModSymmetric sets out = x mod m in the symmetric range [-m/2, m/2).
func (*ModulusBasic) Nat ¶
func (m *ModulusBasic) Nat() *Nat
Nat returns the Nat representation of the modulus.
func (*ModulusBasic) Random ¶
func (m *ModulusBasic) Random(prng io.Reader) (*Nat, error)
Random returns a random Nat in [0, m).
func (*ModulusBasic) Saferith ¶
func (m *ModulusBasic) Saferith() *saferith.Modulus
Saferith returns the underlying saferith.Modulus.
func (*ModulusBasic) SetNat ¶
func (m *ModulusBasic) SetNat(n *Nat) ct.Bool
SetNat sets m = n where n is a Nat.
func (*ModulusBasic) String ¶
func (m *ModulusBasic) String() string
String returns the string representation of the modulus.
type Nat ¶
Nat is a wrapper around saferith.Nat providing additional methods and occasional improvements. This implements the low level constant time interfaces that fiat-crypto implements.
func NewNatFromBig ¶
NewNatFromBig creates a Nat from a big.Int with the given capacity.
func NewNatFromBytes ¶
NewNatFromBytes creates a Nat from a big-endian byte slice.
func NewNatFromSaferith ¶
NewNatFromSaferith creates a Nat from a saferith.Nat.
func (*Nat) AddCap ¶
AddCap sets n = lhs + rhs modulo 2^capacity with capacity capacity. if capacity < 0, capacity will be max(lhs.AnnouncedLen(), rhs.AnnouncedLen()) + 1.
func (*Nat) AnnouncedLen ¶
AnnouncedLen returns the announced length in bits of n. Safe to be used publicly.
func (*Nat) CondAssign ¶
CondAssign sets n = x if choice == 1.
func (*Nat) Div ¶
Div sets n = numerator / denominator. If r is not nil, it will be set it to the remainder. It returns ok=1 if the division was successful, ok=0 otherwise (i.e., division by zero). The number of bits of the quotient will be numerator.AnnouncedLen() and the number of bits of the remainder will be denominator.AnnouncedLen().
func (*Nat) DivVarTime ¶
DivVarTime sets n = numerator / denominator. If r is not nil, it will be set it to the remainder. It returns ok=true if the division was successful, ok=false otherwise (e.g., division by zero). The number of bits of the quotient will be min(numerator.AnnouncedLen(), numerator.AnnouncedLen() - denominator.TrueLen() + 2) and the number of bits of the remainder will be denominator.TrueLen().
func (*Nat) EuclideanDiv ¶
EuclideanDiv sets n to quotient of numerator / denominator. If r is not nil, it will be set it to the remainder. It returns ok=1 if the division was successful, ok=0 otherwise (i.e., division by zero). The number of bits of the quotient will be numerator.AnnouncedLen() and the number of bits of the remainder will be denominator.AnnouncedLen().
func (*Nat) EuclideanDivVarTime ¶
EuclideanDivVarTime sets n to quotient of numerator / denominator. If r is not nil, it will be set it to the remainder. It returns ok=true if the division was successful, ok=false otherwise (e.g., division by zero). The number of bits of the quotient will be min(numerator.AnnouncedLen(), numerator.AnnouncedLen() - denominator.TrueLen() + 2) and the number of bits of the remainder will be denominator.TrueLen().
func (*Nat) FillBytes ¶
FillBytes fills buf with the big-endian byte representation of n and returns buf.
func (*Nat) IsProbablyPrime ¶
IsProbablyPrime returns 1 if n is probably prime, by applying a BPSW test.
func (*Nat) LshCap ¶
LshCap left shifts n by shift bits with given capacity. if capacity < 0, capacity will be x.AnnouncedLen() + shift.
func (*Nat) MarshalCBOR ¶
func (*Nat) MulCap ¶
MulCap sets n = lhs * rhs modulo 2^capacity. if capacity < 0, capacity will be lhs.AnnouncedLen() + rhs.AnnouncedLen().
func (*Nat) NotCap ¶
NotCap sets n = ^x with capacity cap. For compatibility with big.Int.Not, use the announced capacity of x.
func (*Nat) Resize ¶
Resize resizes n to have given capacity. When capacity < 0, use the current announced length When capacity >= 0, use the provided capacity.
func (*Nat) RshCap ¶
RshCap right shifts n by shift bits with given capacity. if capacity < 0, capacity will be x.AnnouncedLen() - shift.
func (*Nat) SetRandomRangeH ¶
SetRandomRangeH sets n to a random value in the range [0, highExclusive). This simply uses rejection sampling to generate a random value in [0, highExclusive) but masks out bits that are too high to be in the range so sampling rejection happens with relatively low probability (~0.5).
func (*Nat) SetRandomRangeLH ¶
SetRandomRangeLH sets n to a random value in the range [lowInclusive, highExclusive).
func (*Nat) Sqrt ¶
Sqrt sets n = sqrt(x) if x is a perfect square, else leaves n unchanged. Returns ok = 1 if n is a perfect square.
func (*Nat) SubCap ¶
SubCap sets n = lhs - rhs modulo 2^capacity. if capacity < 0, capacity will be max(lhs.AnnouncedLen(), rhs.AnnouncedLen()).