1
2
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 }
98
View as plain text