github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/crypto/internal/bigmod/nat.go (about)

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package bigmod
     6  
     7  import (
     8  	"github.com/shogo82148/std/math/big"
     9  )
    10  
    11  // Nat represents an arbitrary natural number
    12  //
    13  // Each Nat has an announced length, which is the number of limbs it has stored.
    14  // Operations on this number are allowed to leak this length, but will not leak
    15  // any information about the values contained in those limbs.
    16  type Nat struct {
    17  	// limbs is little-endian in base 2^W with W = bits.UintSize.
    18  	limbs []uint
    19  }
    20  
    21  // NewNat returns a new nat with a size of zero, just like new(Nat), but with
    22  // the preallocated capacity to hold a number of up to preallocTarget bits.
    23  // NewNat inlines, so the allocation can live on the stack.
    24  func NewNat() *Nat
    25  
    26  // Bytes returns x as a zero-extended big-endian byte slice. The size of the
    27  // slice will match the size of m.
    28  //
    29  // x must have the same size as m and it must be reduced modulo m.
    30  func (x *Nat) Bytes(m *Modulus) []byte
    31  
    32  // SetBytes assigns x = b, where b is a slice of big-endian bytes.
    33  // SetBytes returns an error if b >= m.
    34  //
    35  // The output will be resized to the size of m and overwritten.
    36  func (x *Nat) SetBytes(b []byte, m *Modulus) (*Nat, error)
    37  
    38  // SetOverflowingBytes assigns x = b, where b is a slice of big-endian bytes.
    39  // SetOverflowingBytes returns an error if b has a longer bit length than m, but
    40  // reduces overflowing values up to 2^⌈log2(m)⌉ - 1.
    41  //
    42  // The output will be resized to the size of m and overwritten.
    43  func (x *Nat) SetOverflowingBytes(b []byte, m *Modulus) (*Nat, error)
    44  
    45  // Equal returns 1 if x == y, and 0 otherwise.
    46  //
    47  // Both operands must have the same announced length.
    48  func (x *Nat) Equal(y *Nat) choice
    49  
    50  // IsZero returns 1 if x == 0, and 0 otherwise.
    51  func (x *Nat) IsZero() choice
    52  
    53  // Modulus is used for modular arithmetic, precomputing relevant constants.
    54  //
    55  // Moduli are assumed to be odd numbers. Moduli can also leak the exact
    56  // number of bits needed to store their value, and are stored without padding.
    57  //
    58  // Their actual value is still kept secret.
    59  type Modulus struct {
    60  	// The underlying natural number for this modulus.
    61  	//
    62  	// This will be stored without any padding, and shouldn't alias with any
    63  	// other natural number being used.
    64  	nat     *Nat
    65  	leading int
    66  	m0inv   uint
    67  	rr      *Nat
    68  }
    69  
    70  // NewModulusFromBig creates a new Modulus from a [big.Int].
    71  //
    72  // The Int must be odd. The number of significant bits (and nothing else) is
    73  // leaked through timing side-channels.
    74  func NewModulusFromBig(n *big.Int) (*Modulus, error)
    75  
    76  // Size returns the size of m in bytes.
    77  func (m *Modulus) Size() int
    78  
    79  // BitLen returns the size of m in bits.
    80  func (m *Modulus) BitLen() int
    81  
    82  // Nat returns m as a Nat. The return value must not be written to.
    83  func (m *Modulus) Nat() *Nat
    84  
    85  // Mod calculates out = x mod m.
    86  //
    87  // This works regardless how large the value of x is.
    88  //
    89  // The output will be resized to the size of m and overwritten.
    90  func (out *Nat) Mod(x *Nat, m *Modulus) *Nat
    91  
    92  // ExpandFor ensures x has the right size to work with operations modulo m.
    93  //
    94  // The announced size of x must be smaller than or equal to that of m.
    95  func (x *Nat) ExpandFor(m *Modulus) *Nat
    96  
    97  // Sub computes x = x - y mod m.
    98  //
    99  // The length of both operands must be the same as the modulus. Both operands
   100  // must already be reduced modulo m.
   101  func (x *Nat) Sub(y *Nat, m *Modulus) *Nat
   102  
   103  // Add computes x = x + y mod m.
   104  //
   105  // The length of both operands must be the same as the modulus. Both operands
   106  // must already be reduced modulo m.
   107  func (x *Nat) Add(y *Nat, m *Modulus) *Nat
   108  
   109  // Mul calculates x = x * y mod m.
   110  //
   111  // The length of both operands must be the same as the modulus. Both operands
   112  // must already be reduced modulo m.
   113  func (x *Nat) Mul(y *Nat, m *Modulus) *Nat
   114  
   115  // Exp calculates out = x^e mod m.
   116  //
   117  // The exponent e is represented in big-endian order. The output will be resized
   118  // to the size of m and overwritten. x must already be reduced modulo m.
   119  func (out *Nat) Exp(x *Nat, e []byte, m *Modulus) *Nat
   120  
   121  // ExpShortVarTime calculates out = x^e mod m.
   122  //
   123  // The output will be resized to the size of m and overwritten. x must already
   124  // be reduced modulo m. This leaks the exponent through timing side-channels.
   125  func (out *Nat) ExpShortVarTime(x *Nat, e uint, m *Modulus) *Nat