github.com/cloudflare/circl@v1.5.0/ecc/fourq/fp_generic.go (about)

     1  //go:build go1.12
     2  // +build go1.12
     3  
     4  package fourq
     5  
     6  import (
     7  	"encoding/binary"
     8  	"math/bits"
     9  )
    10  
    11  func fpModGeneric(c *Fp) { fpSubGeneric(c, c, &modulusP) }
    12  
    13  func fpAddGeneric(c, a, b *Fp) {
    14  	a0 := binary.LittleEndian.Uint64(a[0*8 : 1*8])
    15  	a1 := binary.LittleEndian.Uint64(a[1*8 : 2*8])
    16  
    17  	b0 := binary.LittleEndian.Uint64(b[0*8 : 1*8])
    18  	b1 := binary.LittleEndian.Uint64(b[1*8 : 2*8])
    19  
    20  	c0, x := bits.Add64(a0, b0, 0)
    21  	c1, _ := bits.Add64(a1, b1, x)
    22  	c1, x = bits.Add64(c1, c1, 0)
    23  	c0, x = bits.Add64(c0, 0, x)
    24  	c1, _ = bits.Add64(c1>>1, 0, x)
    25  
    26  	binary.LittleEndian.PutUint64(c[0*8:1*8], c0)
    27  	binary.LittleEndian.PutUint64(c[1*8:2*8], c1)
    28  }
    29  
    30  func fpSubGeneric(c, a, b *Fp) {
    31  	a0 := binary.LittleEndian.Uint64(a[0*8 : 1*8])
    32  	a1 := binary.LittleEndian.Uint64(a[1*8 : 2*8])
    33  
    34  	b0 := binary.LittleEndian.Uint64(b[0*8 : 1*8])
    35  	b1 := binary.LittleEndian.Uint64(b[1*8 : 2*8])
    36  
    37  	c0, x := bits.Sub64(a0, b0, 0)
    38  	c1, _ := bits.Sub64(a1, b1, x)
    39  	c1, x = bits.Add64(c1, c1, 0)
    40  	c0, x = bits.Sub64(c0, 0, x)
    41  	c1, _ = bits.Sub64(c1>>1, 0, x)
    42  
    43  	binary.LittleEndian.PutUint64(c[0*8:1*8], c0)
    44  	binary.LittleEndian.PutUint64(c[1*8:2*8], c1)
    45  }
    46  
    47  func fpMulGeneric(c, a, b *Fp) {
    48  	a0 := binary.LittleEndian.Uint64(a[0*8 : 1*8])
    49  	a1 := binary.LittleEndian.Uint64(a[1*8 : 2*8])
    50  
    51  	b0 := binary.LittleEndian.Uint64(b[0*8 : 1*8])
    52  	b1 := binary.LittleEndian.Uint64(b[1*8 : 2*8])
    53  
    54  	c1, c0 := bits.Mul64(a0, b0)
    55  	hi, lo := bits.Mul64(a0, b1)
    56  	c0, x := bits.Add64(c0, hi<<1, 0)
    57  	c1, x = bits.Add64(c1, lo, x)
    58  	c2, _ := bits.Add64(0, 0, x)
    59  
    60  	hi, lo = bits.Mul64(a1, b0)
    61  	c0, x = bits.Add64(c0, hi<<1, 0)
    62  	c1, x = bits.Add64(c1, lo, x)
    63  	c2, _ = bits.Add64(c2, 0, x)
    64  
    65  	hi, lo = bits.Mul64(a1, b1)
    66  	lo, x = bits.Add64(lo, lo, 0)
    67  	hi, _ = bits.Add64(hi, hi, x)
    68  
    69  	c0, x = bits.Add64(c0, lo, 0)
    70  	c1, x = bits.Add64(c1, hi, x)
    71  	c2, _ = bits.Add64(c2, 0, x)
    72  
    73  	c1, x = bits.Add64(c1, c1, 0)
    74  	c0, x = bits.Add64(c0, c2<<1, x)
    75  	c1, _ = bits.Add64(c1>>1, 0, x)
    76  
    77  	c1, x = bits.Add64(c1, c1, 0)
    78  	c0, x = bits.Add64(c0, 0, x)
    79  	c1, _ = bits.Add64(c1>>1, 0, x)
    80  
    81  	binary.LittleEndian.PutUint64(c[0*8:1*8], c0)
    82  	binary.LittleEndian.PutUint64(c[1*8:2*8], c1)
    83  }
    84  
    85  func fpSqrGeneric(c, a *Fp) { fpMulGeneric(c, a, a) }
    86  
    87  func fpHlfGeneric(c, a *Fp) {
    88  	a0 := binary.LittleEndian.Uint64(a[0*8 : 1*8])
    89  	a1 := binary.LittleEndian.Uint64(a[1*8 : 2*8])
    90  
    91  	hlf := a0 & 0x1
    92  	c0 := (a1 << 63) | (a0 >> 1)
    93  	c1 := (hlf << 62) | (a1 >> 1)
    94  
    95  	binary.LittleEndian.PutUint64(c[0*8:1*8], c0)
    96  	binary.LittleEndian.PutUint64(c[1*8:2*8], c1)
    97  }