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