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