-
Notifications
You must be signed in to change notification settings - Fork 61
/
sm2p256.go
134 lines (113 loc) · 3.83 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
132
133
134
// 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)
}
// IsZero returns 1 if e == 0, and zero otherwise.
func (e *SM2P256Element) IsZero() int {
zero := make([]byte, sm2p256ElementLen)
eBytes := e.Bytes()
return subtle.ConstantTimeCompare(eBytes, zero)
}
// 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[:]
}
// 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")
}
// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
var minusOneEncoding = new(SM2P256Element).Sub(
new(SM2P256Element), new(SM2P256Element).One()).Bytes()
for i := range v {
if v[i] < minusOneEncoding[i] {
break
}
if v[i] > minusOneEncoding[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]
}
}