github.com/cloudflare/circl@v1.5.0/math/fp448/fp_generic.go (about)

     1  package fp448
     2  
     3  import (
     4  	"encoding/binary"
     5  	"math/bits"
     6  )
     7  
     8  func cmovGeneric(x, y *Elt, n uint) {
     9  	m := -uint64(n & 0x1)
    10  	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
    11  	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
    12  	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
    13  	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
    14  	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
    15  	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
    16  	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
    17  
    18  	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
    19  	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
    20  	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
    21  	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
    22  	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
    23  	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
    24  	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
    25  
    26  	x0 = (x0 &^ m) | (y0 & m)
    27  	x1 = (x1 &^ m) | (y1 & m)
    28  	x2 = (x2 &^ m) | (y2 & m)
    29  	x3 = (x3 &^ m) | (y3 & m)
    30  	x4 = (x4 &^ m) | (y4 & m)
    31  	x5 = (x5 &^ m) | (y5 & m)
    32  	x6 = (x6 &^ m) | (y6 & m)
    33  
    34  	binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
    35  	binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
    36  	binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
    37  	binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
    38  	binary.LittleEndian.PutUint64(x[4*8:5*8], x4)
    39  	binary.LittleEndian.PutUint64(x[5*8:6*8], x5)
    40  	binary.LittleEndian.PutUint64(x[6*8:7*8], x6)
    41  }
    42  
    43  func cswapGeneric(x, y *Elt, n uint) {
    44  	m := -uint64(n & 0x1)
    45  	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
    46  	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
    47  	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
    48  	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
    49  	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
    50  	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
    51  	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
    52  
    53  	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
    54  	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
    55  	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
    56  	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
    57  	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
    58  	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
    59  	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
    60  
    61  	t0 := m & (x0 ^ y0)
    62  	t1 := m & (x1 ^ y1)
    63  	t2 := m & (x2 ^ y2)
    64  	t3 := m & (x3 ^ y3)
    65  	t4 := m & (x4 ^ y4)
    66  	t5 := m & (x5 ^ y5)
    67  	t6 := m & (x6 ^ y6)
    68  	x0 ^= t0
    69  	x1 ^= t1
    70  	x2 ^= t2
    71  	x3 ^= t3
    72  	x4 ^= t4
    73  	x5 ^= t5
    74  	x6 ^= t6
    75  	y0 ^= t0
    76  	y1 ^= t1
    77  	y2 ^= t2
    78  	y3 ^= t3
    79  	y4 ^= t4
    80  	y5 ^= t5
    81  	y6 ^= t6
    82  
    83  	binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
    84  	binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
    85  	binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
    86  	binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
    87  	binary.LittleEndian.PutUint64(x[4*8:5*8], x4)
    88  	binary.LittleEndian.PutUint64(x[5*8:6*8], x5)
    89  	binary.LittleEndian.PutUint64(x[6*8:7*8], x6)
    90  
    91  	binary.LittleEndian.PutUint64(y[0*8:1*8], y0)
    92  	binary.LittleEndian.PutUint64(y[1*8:2*8], y1)
    93  	binary.LittleEndian.PutUint64(y[2*8:3*8], y2)
    94  	binary.LittleEndian.PutUint64(y[3*8:4*8], y3)
    95  	binary.LittleEndian.PutUint64(y[4*8:5*8], y4)
    96  	binary.LittleEndian.PutUint64(y[5*8:6*8], y5)
    97  	binary.LittleEndian.PutUint64(y[6*8:7*8], y6)
    98  }
    99  
   100  func addGeneric(z, x, y *Elt) {
   101  	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
   102  	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
   103  	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
   104  	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
   105  	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
   106  	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
   107  	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
   108  
   109  	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
   110  	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
   111  	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
   112  	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
   113  	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
   114  	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
   115  	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
   116  
   117  	z0, c0 := bits.Add64(x0, y0, 0)
   118  	z1, c1 := bits.Add64(x1, y1, c0)
   119  	z2, c2 := bits.Add64(x2, y2, c1)
   120  	z3, c3 := bits.Add64(x3, y3, c2)
   121  	z4, c4 := bits.Add64(x4, y4, c3)
   122  	z5, c5 := bits.Add64(x5, y5, c4)
   123  	z6, z7 := bits.Add64(x6, y6, c5)
   124  
   125  	z0, c0 = bits.Add64(z0, z7, 0)
   126  	z1, c1 = bits.Add64(z1, 0, c0)
   127  	z2, c2 = bits.Add64(z2, 0, c1)
   128  	z3, c3 = bits.Add64(z3, z7<<32, c2)
   129  	z4, c4 = bits.Add64(z4, 0, c3)
   130  	z5, c5 = bits.Add64(z5, 0, c4)
   131  	z6, z7 = bits.Add64(z6, 0, c5)
   132  
   133  	z0, c0 = bits.Add64(z0, z7, 0)
   134  	z1, c1 = bits.Add64(z1, 0, c0)
   135  	z2, c2 = bits.Add64(z2, 0, c1)
   136  	z3, c3 = bits.Add64(z3, z7<<32, c2)
   137  	z4, c4 = bits.Add64(z4, 0, c3)
   138  	z5, c5 = bits.Add64(z5, 0, c4)
   139  	z6, _ = bits.Add64(z6, 0, c5)
   140  
   141  	binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
   142  	binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
   143  	binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
   144  	binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
   145  	binary.LittleEndian.PutUint64(z[4*8:5*8], z4)
   146  	binary.LittleEndian.PutUint64(z[5*8:6*8], z5)
   147  	binary.LittleEndian.PutUint64(z[6*8:7*8], z6)
   148  }
   149  
   150  func subGeneric(z, x, y *Elt) {
   151  	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
   152  	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
   153  	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
   154  	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
   155  	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
   156  	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
   157  	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
   158  
   159  	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
   160  	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
   161  	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
   162  	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
   163  	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
   164  	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
   165  	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
   166  
   167  	z0, c0 := bits.Sub64(x0, y0, 0)
   168  	z1, c1 := bits.Sub64(x1, y1, c0)
   169  	z2, c2 := bits.Sub64(x2, y2, c1)
   170  	z3, c3 := bits.Sub64(x3, y3, c2)
   171  	z4, c4 := bits.Sub64(x4, y4, c3)
   172  	z5, c5 := bits.Sub64(x5, y5, c4)
   173  	z6, z7 := bits.Sub64(x6, y6, c5)
   174  
   175  	z0, c0 = bits.Sub64(z0, z7, 0)
   176  	z1, c1 = bits.Sub64(z1, 0, c0)
   177  	z2, c2 = bits.Sub64(z2, 0, c1)
   178  	z3, c3 = bits.Sub64(z3, z7<<32, c2)
   179  	z4, c4 = bits.Sub64(z4, 0, c3)
   180  	z5, c5 = bits.Sub64(z5, 0, c4)
   181  	z6, z7 = bits.Sub64(z6, 0, c5)
   182  
   183  	z0, c0 = bits.Sub64(z0, z7, 0)
   184  	z1, c1 = bits.Sub64(z1, 0, c0)
   185  	z2, c2 = bits.Sub64(z2, 0, c1)
   186  	z3, c3 = bits.Sub64(z3, z7<<32, c2)
   187  	z4, c4 = bits.Sub64(z4, 0, c3)
   188  	z5, c5 = bits.Sub64(z5, 0, c4)
   189  	z6, _ = bits.Sub64(z6, 0, c5)
   190  
   191  	binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
   192  	binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
   193  	binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
   194  	binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
   195  	binary.LittleEndian.PutUint64(z[4*8:5*8], z4)
   196  	binary.LittleEndian.PutUint64(z[5*8:6*8], z5)
   197  	binary.LittleEndian.PutUint64(z[6*8:7*8], z6)
   198  }
   199  
   200  func addsubGeneric(x, y *Elt) {
   201  	z := &Elt{}
   202  	addGeneric(z, x, y)
   203  	subGeneric(y, x, y)
   204  	*x = *z
   205  }
   206  
   207  func mulGeneric(z, x, y *Elt) {
   208  	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
   209  	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
   210  	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
   211  	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
   212  	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
   213  	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
   214  	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
   215  
   216  	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
   217  	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
   218  	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
   219  	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
   220  	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
   221  	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
   222  	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
   223  
   224  	yy := [7]uint64{y0, y1, y2, y3, y4, y5, y6}
   225  	zz := [7]uint64{}
   226  
   227  	yi := yy[0]
   228  	h0, l0 := bits.Mul64(x0, yi)
   229  	h1, l1 := bits.Mul64(x1, yi)
   230  	h2, l2 := bits.Mul64(x2, yi)
   231  	h3, l3 := bits.Mul64(x3, yi)
   232  	h4, l4 := bits.Mul64(x4, yi)
   233  	h5, l5 := bits.Mul64(x5, yi)
   234  	h6, l6 := bits.Mul64(x6, yi)
   235  
   236  	zz[0] = l0
   237  	a0, c0 := bits.Add64(h0, l1, 0)
   238  	a1, c1 := bits.Add64(h1, l2, c0)
   239  	a2, c2 := bits.Add64(h2, l3, c1)
   240  	a3, c3 := bits.Add64(h3, l4, c2)
   241  	a4, c4 := bits.Add64(h4, l5, c3)
   242  	a5, c5 := bits.Add64(h5, l6, c4)
   243  	a6, _ := bits.Add64(h6, 0, c5)
   244  
   245  	for i := 1; i < 7; i++ {
   246  		yi = yy[i]
   247  		h0, l0 = bits.Mul64(x0, yi)
   248  		h1, l1 = bits.Mul64(x1, yi)
   249  		h2, l2 = bits.Mul64(x2, yi)
   250  		h3, l3 = bits.Mul64(x3, yi)
   251  		h4, l4 = bits.Mul64(x4, yi)
   252  		h5, l5 = bits.Mul64(x5, yi)
   253  		h6, l6 = bits.Mul64(x6, yi)
   254  
   255  		zz[i], c0 = bits.Add64(a0, l0, 0)
   256  		a0, c1 = bits.Add64(a1, l1, c0)
   257  		a1, c2 = bits.Add64(a2, l2, c1)
   258  		a2, c3 = bits.Add64(a3, l3, c2)
   259  		a3, c4 = bits.Add64(a4, l4, c3)
   260  		a4, c5 = bits.Add64(a5, l5, c4)
   261  		a5, a6 = bits.Add64(a6, l6, c5)
   262  
   263  		a0, c0 = bits.Add64(a0, h0, 0)
   264  		a1, c1 = bits.Add64(a1, h1, c0)
   265  		a2, c2 = bits.Add64(a2, h2, c1)
   266  		a3, c3 = bits.Add64(a3, h3, c2)
   267  		a4, c4 = bits.Add64(a4, h4, c3)
   268  		a5, c5 = bits.Add64(a5, h5, c4)
   269  		a6, _ = bits.Add64(a6, h6, c5)
   270  	}
   271  	red64(z, &zz, &[7]uint64{a0, a1, a2, a3, a4, a5, a6})
   272  }
   273  
   274  func sqrGeneric(z, x *Elt) { mulGeneric(z, x, x) }
   275  
   276  func red64(z *Elt, l, h *[7]uint64) {
   277  	/* (2C13, 2C12, 2C11, 2C10|C10, C9, C8, C7) + (C6,...,C0) */
   278  	h0 := h[0]
   279  	h1 := h[1]
   280  	h2 := h[2]
   281  	h3 := ((h[3] & (0xFFFFFFFF << 32)) << 1) | (h[3] & 0xFFFFFFFF)
   282  	h4 := (h[3] >> 63) | (h[4] << 1)
   283  	h5 := (h[4] >> 63) | (h[5] << 1)
   284  	h6 := (h[5] >> 63) | (h[6] << 1)
   285  	h7 := (h[6] >> 63)
   286  
   287  	l0, c0 := bits.Add64(h0, l[0], 0)
   288  	l1, c1 := bits.Add64(h1, l[1], c0)
   289  	l2, c2 := bits.Add64(h2, l[2], c1)
   290  	l3, c3 := bits.Add64(h3, l[3], c2)
   291  	l4, c4 := bits.Add64(h4, l[4], c3)
   292  	l5, c5 := bits.Add64(h5, l[5], c4)
   293  	l6, c6 := bits.Add64(h6, l[6], c5)
   294  	l7, _ := bits.Add64(h7, 0, c6)
   295  
   296  	/* (C10C9, C9C8,C8C7,C7C13,C13C12,C12C11,C11C10) + (C6,...,C0) */
   297  	h0 = (h[3] >> 32) | (h[4] << 32)
   298  	h1 = (h[4] >> 32) | (h[5] << 32)
   299  	h2 = (h[5] >> 32) | (h[6] << 32)
   300  	h3 = (h[6] >> 32) | (h[0] << 32)
   301  	h4 = (h[0] >> 32) | (h[1] << 32)
   302  	h5 = (h[1] >> 32) | (h[2] << 32)
   303  	h6 = (h[2] >> 32) | (h[3] << 32)
   304  
   305  	l0, c0 = bits.Add64(l0, h0, 0)
   306  	l1, c1 = bits.Add64(l1, h1, c0)
   307  	l2, c2 = bits.Add64(l2, h2, c1)
   308  	l3, c3 = bits.Add64(l3, h3, c2)
   309  	l4, c4 = bits.Add64(l4, h4, c3)
   310  	l5, c5 = bits.Add64(l5, h5, c4)
   311  	l6, c6 = bits.Add64(l6, h6, c5)
   312  	l7, _ = bits.Add64(l7, 0, c6)
   313  
   314  	/* (C7) + (C6,...,C0) */
   315  	l0, c0 = bits.Add64(l0, l7, 0)
   316  	l1, c1 = bits.Add64(l1, 0, c0)
   317  	l2, c2 = bits.Add64(l2, 0, c1)
   318  	l3, c3 = bits.Add64(l3, l7<<32, c2)
   319  	l4, c4 = bits.Add64(l4, 0, c3)
   320  	l5, c5 = bits.Add64(l5, 0, c4)
   321  	l6, l7 = bits.Add64(l6, 0, c5)
   322  
   323  	/* (C7) + (C6,...,C0) */
   324  	l0, c0 = bits.Add64(l0, l7, 0)
   325  	l1, c1 = bits.Add64(l1, 0, c0)
   326  	l2, c2 = bits.Add64(l2, 0, c1)
   327  	l3, c3 = bits.Add64(l3, l7<<32, c2)
   328  	l4, c4 = bits.Add64(l4, 0, c3)
   329  	l5, c5 = bits.Add64(l5, 0, c4)
   330  	l6, _ = bits.Add64(l6, 0, c5)
   331  
   332  	binary.LittleEndian.PutUint64(z[0*8:1*8], l0)
   333  	binary.LittleEndian.PutUint64(z[1*8:2*8], l1)
   334  	binary.LittleEndian.PutUint64(z[2*8:3*8], l2)
   335  	binary.LittleEndian.PutUint64(z[3*8:4*8], l3)
   336  	binary.LittleEndian.PutUint64(z[4*8:5*8], l4)
   337  	binary.LittleEndian.PutUint64(z[5*8:6*8], l5)
   338  	binary.LittleEndian.PutUint64(z[6*8:7*8], l6)
   339  }