-
Notifications
You must be signed in to change notification settings - Fork 54
/
sm2p256.go
131 lines (114 loc) · 3.92 KB
/
sm2p256.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated by generate.go. DO NOT EDIT.
package fiat
import (
"crypto/subtle"
"errors"
)
// SM2P256Element is an integer modulo 2^256 - 2^224 - 2^96 + 2^64 - 1.
//
// The zero value is a valid zero element.
type SM2P256Element struct {
// Values are represented internally always in the Montgomery domain, and
// converted in Bytes and SetBytes.
x sm2p256MontgomeryDomainFieldElement
}
const sm2p256ElementLen = 32
type sm2p256UntypedFieldElement = [4]uint64
// One sets e = 1, and returns e.
func (e *SM2P256Element) One() *SM2P256Element {
sm2p256SetOne(&e.x)
return e
}
// Equal returns 1 if e == t, and zero otherwise.
func (e *SM2P256Element) Equal(t *SM2P256Element) int {
eBytes := e.Bytes()
tBytes := t.Bytes()
return subtle.ConstantTimeCompare(eBytes, tBytes)
}
var sm2p256ZeroEncoding = new(SM2P256Element).Bytes()
// IsZero returns 1 if e == 0, and zero otherwise.
func (e *SM2P256Element) IsZero() int {
eBytes := e.Bytes()
return subtle.ConstantTimeCompare(eBytes, sm2p256ZeroEncoding)
}
// Set sets e = t, and returns e.
func (e *SM2P256Element) Set(t *SM2P256Element) *SM2P256Element {
e.x = t.x
return e
}
// Bytes returns the 32-byte big-endian encoding of e.
func (e *SM2P256Element) Bytes() []byte {
// This function is outlined to make the allocations inline in the caller
// rather than happen on the heap.
var out [sm2p256ElementLen]byte
return e.bytes(&out)
}
func (e *SM2P256Element) bytes(out *[sm2p256ElementLen]byte) []byte {
var tmp sm2p256NonMontgomeryDomainFieldElement
sm2p256FromMontgomery(&tmp, &e.x)
sm2p256ToBytes(out, (*sm2p256UntypedFieldElement)(&tmp))
sm2p256InvertEndianness(out[:])
return out[:]
}
// sm2p256MinusOneEncoding is the encoding of -1 mod p, so p - 1, the
// highest canonical encoding. It is used by SetBytes to check for non-canonical
// encodings such as p + k, 2p + k, etc.
var sm2p256MinusOneEncoding = new(SM2P256Element).Sub(
new(SM2P256Element), new(SM2P256Element).One()).Bytes()
// SetBytes sets e = v, where v is a big-endian 32-byte encoding, and returns e.
// If v is not 32 bytes or it encodes a value higher than 2^256 - 2^224 - 2^96 + 2^64 - 1,
// SetBytes returns nil and an error, and e is unchanged.
func (e *SM2P256Element) SetBytes(v []byte) (*SM2P256Element, error) {
if len(v) != sm2p256ElementLen {
return nil, errors.New("invalid SM2P256Element encoding")
}
for i := range v {
if v[i] < sm2p256MinusOneEncoding[i] {
break
}
if v[i] > sm2p256MinusOneEncoding[i] {
return nil, errors.New("invalid SM2P256Element encoding")
}
}
var in [sm2p256ElementLen]byte
copy(in[:], v)
sm2p256InvertEndianness(in[:])
var tmp sm2p256NonMontgomeryDomainFieldElement
sm2p256FromBytes((*sm2p256UntypedFieldElement)(&tmp), &in)
sm2p256ToMontgomery(&e.x, &tmp)
return e, nil
}
// Add sets e = t1 + t2, and returns e.
func (e *SM2P256Element) Add(t1, t2 *SM2P256Element) *SM2P256Element {
sm2p256Add(&e.x, &t1.x, &t2.x)
return e
}
// Sub sets e = t1 - t2, and returns e.
func (e *SM2P256Element) Sub(t1, t2 *SM2P256Element) *SM2P256Element {
sm2p256Sub(&e.x, &t1.x, &t2.x)
return e
}
// Mul sets e = t1 * t2, and returns e.
func (e *SM2P256Element) Mul(t1, t2 *SM2P256Element) *SM2P256Element {
sm2p256Mul(&e.x, &t1.x, &t2.x)
return e
}
// Square sets e = t * t, and returns e.
func (e *SM2P256Element) Square(t *SM2P256Element) *SM2P256Element {
sm2p256Square(&e.x, &t.x)
return e
}
// Select sets v to a if cond == 1, and to b if cond == 0.
func (v *SM2P256Element) Select(a, b *SM2P256Element, cond int) *SM2P256Element {
sm2p256Selectznz((*sm2p256UntypedFieldElement)(&v.x), sm2p256Uint1(cond),
(*sm2p256UntypedFieldElement)(&b.x), (*sm2p256UntypedFieldElement)(&a.x))
return v
}
func sm2p256InvertEndianness(v []byte) {
for i := 0; i < len(v)/2; i++ {
v[i], v[len(v)-1-i] = v[len(v)-1-i], v[i]
}
}