-
Notifications
You must be signed in to change notification settings - Fork 143
/
fp.go
113 lines (102 loc) · 2.12 KB
/
fp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package fourq
import (
"math/big"
"github.com/cloudflare/circl/internal/conv"
)
var modulusP = Fp{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
}
// SizeFp is the length in bytes to represent an element in the base field.
const SizeFp = 16
// Fp is an element (in littleEndian order) of prime field GF(2^127-1).
type Fp [SizeFp]byte
func (f *Fp) String() string { return conv.BytesLe2Hex(f[:]) }
func (f *Fp) isZero() bool { fpMod(f); return *f == Fp{} }
func (f *Fp) toBigInt() *big.Int { fpMod(f); return conv.BytesLe2BigInt(f[:]) }
func (f *Fp) setBigInt(b *big.Int) { conv.BigInt2BytesLe((*f)[:], b); fpMod(f) }
func (f *Fp) toBytes(buf []byte) {
if len(buf) == SizeFp {
fpMod(f)
copy(buf, f[:])
}
}
func (f *Fp) fromBytes(buf []byte) bool {
if len(buf) == SizeFp {
if (buf[SizeFp-1] >> 7) == 0 {
copy(f[:], buf)
fpMod(f)
return true
}
}
return false
}
func fpNeg(c, a *Fp) { fpSub(c, &modulusP, a) }
// fqSgn returns the sign of an element.
//
// -1 if x > (p+1)/2
// 0 if x == 0
// +1 if x > (p+1)/2.
func fpSgn(c *Fp) int {
s := 0
if !c.isZero() {
b := int(c[SizeFp-1]>>6) & 0x1
s = 1 - (b << 1)
}
return s
}
// fpTwo1251 sets c = a^(2^125-1).
func fpTwo1251(c, a *Fp) {
t1, t2, t3, t4, t5 := &Fp{}, &Fp{}, &Fp{}, &Fp{}, &Fp{}
fpSqr(t2, a)
fpMul(t2, t2, a)
fpSqr(t3, t2)
fpSqr(t3, t3)
fpMul(t3, t3, t2)
fpSqr(t4, t3)
fpSqr(t4, t4)
fpSqr(t4, t4)
fpSqr(t4, t4)
fpMul(t4, t4, t3)
fpSqr(t5, t4)
for i := 0; i < 7; i++ {
fpSqr(t5, t5)
}
fpMul(t5, t5, t4)
fpSqr(t2, t5)
for i := 0; i < 15; i++ {
fpSqr(t2, t2)
}
fpMul(t2, t2, t5)
fpSqr(t1, t2)
for i := 0; i < 31; i++ {
fpSqr(t1, t1)
}
fpMul(t1, t1, t2)
for i := 0; i < 32; i++ {
fpSqr(t1, t1)
}
fpMul(t1, t2, t1)
for i := 0; i < 16; i++ {
fpSqr(t1, t1)
}
fpMul(t1, t1, t5)
for i := 0; i < 8; i++ {
fpSqr(t1, t1)
}
fpMul(t1, t1, t4)
for i := 0; i < 4; i++ {
fpSqr(t1, t1)
}
fpMul(t1, t1, t3)
fpSqr(t1, t1)
fpMul(c, a, t1)
}
// fpInv sets z to a^(-1) mod p.
func fpInv(z, a *Fp) {
t := &Fp{}
fpTwo1251(t, a)
fpSqr(t, t)
fpSqr(t, t)
fpMul(z, t, a)
}