1
2
3
4
5
6
7 package fiat
8
9 import (
10 "crypto/internal/fips140/subtle"
11 "errors"
12 )
13
14
15
16
17 type P256Element struct {
18
19
20 x p256MontgomeryDomainFieldElement
21 }
22
23 const p256ElementLen = 32
24
25 type p256UntypedFieldElement = [4]uint64
26
27
28 func (e *P256Element) One() *P256Element {
29 p256SetOne(&e.x)
30 return e
31 }
32
33
34 func (e *P256Element) Equal(t *P256Element) int {
35 eBytes := e.Bytes()
36 tBytes := t.Bytes()
37 return subtle.ConstantTimeCompare(eBytes, tBytes)
38 }
39
40
41 func (e *P256Element) IsZero() int {
42 zero := make([]byte, p256ElementLen)
43 eBytes := e.Bytes()
44 return subtle.ConstantTimeCompare(eBytes, zero)
45 }
46
47
48 func (e *P256Element) Set(t *P256Element) *P256Element {
49 e.x = t.x
50 return e
51 }
52
53
54 func (e *P256Element) Bytes() []byte {
55
56
57 var out [p256ElementLen]byte
58 return e.bytes(&out)
59 }
60
61 func (e *P256Element) bytes(out *[p256ElementLen]byte) []byte {
62 var tmp p256NonMontgomeryDomainFieldElement
63 p256FromMontgomery(&tmp, &e.x)
64 p256ToBytes(out, (*p256UntypedFieldElement)(&tmp))
65 p256InvertEndianness(out[:])
66 return out[:]
67 }
68
69
70
71
72 func (e *P256Element) SetBytes(v []byte) (*P256Element, error) {
73 if len(v) != p256ElementLen {
74 return nil, errors.New("invalid P256Element encoding")
75 }
76
77
78
79 var minusOneEncoding = new(P256Element).Sub(
80 new(P256Element), new(P256Element).One()).Bytes()
81 for i := range v {
82 if v[i] < minusOneEncoding[i] {
83 break
84 }
85 if v[i] > minusOneEncoding[i] {
86 return nil, errors.New("invalid P256Element encoding")
87 }
88 }
89
90 var in [p256ElementLen]byte
91 copy(in[:], v)
92 p256InvertEndianness(in[:])
93 var tmp p256NonMontgomeryDomainFieldElement
94 p256FromBytes((*p256UntypedFieldElement)(&tmp), &in)
95 p256ToMontgomery(&e.x, &tmp)
96 return e, nil
97 }
98
99
100 func (e *P256Element) Add(t1, t2 *P256Element) *P256Element {
101 p256Add(&e.x, &t1.x, &t2.x)
102 return e
103 }
104
105
106 func (e *P256Element) Sub(t1, t2 *P256Element) *P256Element {
107 p256Sub(&e.x, &t1.x, &t2.x)
108 return e
109 }
110
111
112 func (e *P256Element) Mul(t1, t2 *P256Element) *P256Element {
113 p256Mul(&e.x, &t1.x, &t2.x)
114 return e
115 }
116
117
118 func (e *P256Element) Square(t *P256Element) *P256Element {
119 p256Square(&e.x, &t.x)
120 return e
121 }
122
123
124 func (v *P256Element) Select(a, b *P256Element, cond int) *P256Element {
125 p256Selectznz((*p256UntypedFieldElement)(&v.x), p256Uint1(cond),
126 (*p256UntypedFieldElement)(&b.x), (*p256UntypedFieldElement)(&a.x))
127 return v
128 }
129
130 func p256InvertEndianness(v []byte) {
131 for i := 0; i < len(v)/2; i++ {
132 v[i], v[len(v)-1-i] = v[len(v)-1-i], v[i]
133 }
134 }
135
View as plain text