github.com/cloudflare/circl@v1.5.0/ecc/p384/arith.go (about)

     1  //go:build (!purego && arm64) || (!purego && amd64)
     2  // +build !purego,arm64 !purego,amd64
     3  
     4  package p384
     5  
     6  import (
     7  	"math/big"
     8  
     9  	"github.com/cloudflare/circl/internal/conv"
    10  )
    11  
    12  const sizeFp = 48
    13  
    14  type fp384 [sizeFp]byte
    15  
    16  func (e fp384) BigInt() *big.Int { return conv.BytesLe2BigInt(e[:]) }
    17  func (e fp384) String() string   { return conv.BytesLe2Hex(e[:]) }
    18  
    19  func (e *fp384) SetBigInt(b *big.Int) {
    20  	if b.BitLen() > 384 || b.Sign() < 0 {
    21  		b = new(big.Int).Mod(b, p.BigInt())
    22  	}
    23  	conv.BigInt2BytesLe(e[:], b)
    24  }
    25  
    26  func montEncode(c, a *fp384) { fp384Mul(c, a, &r2) }
    27  func montDecode(c, a *fp384) { fp384Mul(c, a, &fp384{1}) }
    28  func fp384Sqr(c, a *fp384)   { fp384Mul(c, a, a) }
    29  
    30  func fp384Inv(z, x *fp384) {
    31  	t0, t1, t2, t3, t4 := &fp384{}, &fp384{}, &fp384{}, &fp384{}, &fp384{}
    32  	/* alpha_1 */
    33  	fp384Sqr(t4, x)
    34  	/* alpha_2 */
    35  	fp384Mul(t4, t4, x)
    36  	/* alpha_3 */
    37  	fp384Sqr(t0, t4)
    38  	fp384Mul(t0, t0, x)
    39  	/* alpha_6 */
    40  	fp384Sqr(t1, t0)
    41  	fp384Sqr(t1, t1)
    42  	fp384Sqr(t1, t1)
    43  	fp384Mul(t1, t1, t0)
    44  	/* alpha_12 */
    45  	fp384Sqr(t2, t1)
    46  	for i := 0; i < 5; i++ {
    47  		fp384Sqr(t2, t2)
    48  	}
    49  	fp384Mul(t2, t2, t1)
    50  	/* alpha_15 */
    51  	for i := 0; i < 3; i++ {
    52  		fp384Sqr(t2, t2)
    53  	}
    54  	fp384Mul(t2, t2, t0)
    55  	/* alpha_30 */
    56  	fp384Sqr(t1, t2)
    57  	for i := 0; i < 14; i++ {
    58  		fp384Sqr(t1, t1)
    59  	}
    60  	fp384Mul(t1, t1, t2)
    61  	/* alpha_60 */
    62  	fp384Sqr(t3, t1)
    63  	for i := 0; i < 29; i++ {
    64  		fp384Sqr(t3, t3)
    65  	}
    66  	fp384Mul(t3, t3, t1)
    67  	/* T_3 = alpha_30^(2^2) */
    68  	fp384Sqr(t1, t1)
    69  	fp384Sqr(t1, t1)
    70  	/* alpha_32 */
    71  	*t0 = *t1
    72  	fp384Mul(t0, t0, t4)
    73  	/* T_3 = a^(2^32-3) = (alpha_30)^(2^2)*alpha_1 */
    74  	fp384Mul(t1, t1, x)
    75  	/* alpha_120 */
    76  	fp384Sqr(t4, t3)
    77  	for i := 0; i < 59; i++ {
    78  		fp384Sqr(t4, t4)
    79  	}
    80  	fp384Mul(t4, t4, t3)
    81  	/* alpha_240 */
    82  	fp384Sqr(t3, t4)
    83  	for i := 0; i < 119; i++ {
    84  		fp384Sqr(t3, t3)
    85  	}
    86  	fp384Mul(t3, t3, t4)
    87  	/* alpha_255 */
    88  	for i := 0; i < 15; i++ {
    89  		fp384Sqr(t3, t3)
    90  	}
    91  	fp384Mul(t3, t3, t2)
    92  	/* T_5 = a^(2^288-2^32-1) = (alpha_255)^(2^33)*alpha_32 */
    93  	for i := 0; i < 33; i++ {
    94  		fp384Sqr(t3, t3)
    95  	}
    96  	fp384Mul(t3, t3, t0)
    97  	/* T_1 = a^(2^384-2^128-2^96+2^32-3) = (T_1)^(2^96)*T_3 */
    98  	fp384Sqr(t4, t3)
    99  	for i := 0; i < 95; i++ {
   100  		fp384Sqr(t4, t4)
   101  	}
   102  	fp384Mul(z, t4, t1)
   103  }
   104  
   105  //go:noescape
   106  func fp384Cmov(x, y *fp384, b int)
   107  
   108  //go:noescape
   109  func fp384Neg(c, a *fp384)
   110  
   111  //go:noescape
   112  func fp384Add(c, a, b *fp384)
   113  
   114  //go:noescape
   115  func fp384Sub(c, a, b *fp384)
   116  
   117  //go:noescape
   118  func fp384Mul(c, a, b *fp384)
   119  
   120  var (
   121  	// p is the order of the base field, represented as little-endian 64-bit words.
   122  	p = fp384{
   123  		0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   124  		0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   125  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   126  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   127  	}
   128  	// pp satisfies r*rp - p*pp = 1 where rp and pp are both integers.
   129  	pp = fp384{ //nolint
   130  		0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
   131  		0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff,
   132  		0xfa, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00,
   133  		0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
   134  	}
   135  	// r2 is R^2 where R = 2^384 mod p.
   136  	r2 = fp384{
   137  		0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
   138  		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
   139  		0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
   140  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   141  	}
   142  	// bb is the Montgomery encoding of the curve parameter B.
   143  	bb = fp384{
   144  		0xcc, 0x2d, 0x41, 0x9d, 0x71, 0x88, 0x11, 0x08, 0xec, 0x32, 0x4c, 0x7a,
   145  		0xd8, 0xad, 0x29, 0xf7, 0x2e, 0x02, 0x20, 0x19, 0x9b, 0x20, 0xf2, 0x77,
   146  		0xe2, 0x8a, 0x93, 0x94, 0xee, 0x4b, 0x37, 0xe3, 0x94, 0x20, 0x02, 0x1f,
   147  		0xf4, 0x21, 0x2b, 0xb6, 0xf9, 0xbf, 0x4f, 0x60, 0x4b, 0x11, 0x08, 0xcd,
   148  	}
   149  )