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 P384Element struct {
18
19
20 x p384MontgomeryDomainFieldElement
21 }
22
23 const p384ElementLen = 48
24
25 type p384UntypedFieldElement = [6]uint64
26
27
28 func (e *P384Element) One() *P384Element {
29 p384SetOne(&e.x)
30 return e
31 }
32
33
34 func (e *P384Element) Equal(t *P384Element) int {
35 eBytes := e.Bytes()
36 tBytes := t.Bytes()
37 return subtle.ConstantTimeCompare(eBytes, tBytes)
38 }
39
40
41 func (e *P384Element) IsZero() int {
42 zero := make([]byte, p384ElementLen)
43 eBytes := e.Bytes()
44 return subtle.ConstantTimeCompare(eBytes, zero)
45 }
46
47
48 func (e *P384Element) Set(t *P384Element) *P384Element {
49 e.x = t.x
50 return e
51 }
52
53
54 func (e *P384Element) Bytes() []byte {
55
56
57 var out [p384ElementLen]byte
58 return e.bytes(&out)
59 }
60
61 func (e *P384Element) bytes(out *[p384ElementLen]byte) []byte {
62 var tmp p384NonMontgomeryDomainFieldElement
63 p384FromMontgomery(&tmp, &e.x)
64 p384ToBytes(out, (*p384UntypedFieldElement)(&tmp))
65 p384InvertEndianness(out[:])
66 return out[:]
67 }
68
69
70
71
72 func (e *P384Element) SetBytes(v []byte) (*P384Element, error) {
73 if len(v) != p384ElementLen {
74 return nil, errors.New("invalid P384Element encoding")
75 }
76
77
78
79 var minusOneEncoding = new(P384Element).Sub(
80 new(P384Element), new(P384Element).One()).Bytes()
81 if subtle.ConstantTimeLessOrEqBytes(v, minusOneEncoding) == 0 {
82 return nil, errors.New("invalid P384Element encoding")
83 }
84
85 var in [p384ElementLen]byte
86 copy(in[:], v)
87 p384InvertEndianness(in[:])
88 var tmp p384NonMontgomeryDomainFieldElement
89 p384FromBytes((*p384UntypedFieldElement)(&tmp), &in)
90 p384ToMontgomery(&e.x, &tmp)
91 return e, nil
92 }
93
94
95 func (e *P384Element) Add(t1, t2 *P384Element) *P384Element {
96 p384Add(&e.x, &t1.x, &t2.x)
97 return e
98 }
99
100
101 func (e *P384Element) Sub(t1, t2 *P384Element) *P384Element {
102 p384Sub(&e.x, &t1.x, &t2.x)
103 return e
104 }
105
106
107 func (e *P384Element) Mul(t1, t2 *P384Element) *P384Element {
108 p384Mul(&e.x, &t1.x, &t2.x)
109 return e
110 }
111
112
113 func (e *P384Element) Square(t *P384Element) *P384Element {
114 p384Square(&e.x, &t.x)
115 return e
116 }
117
118
119 func (v *P384Element) Select(a, b *P384Element, cond int) *P384Element {
120 p384Selectznz((*p384UntypedFieldElement)(&v.x), p384Uint1(cond),
121 (*p384UntypedFieldElement)(&b.x), (*p384UntypedFieldElement)(&a.x))
122 return v
123 }
124
125 func p384InvertEndianness(v []byte) {
126 for i := 0; i < len(v)/2; i++ {
127 v[i], v[len(v)-1-i] = v[len(v)-1-i], v[i]
128 }
129 }
130
View as plain text