-
Notifications
You must be signed in to change notification settings - Fork 136
/
mayo.go
185 lines (156 loc) · 5.01 KB
/
mayo.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Code generated from modePkg.templ.go. DO NOT EDIT.
// mode1 implements the MAYO signature scheme MAYO_1
// as submitted to round1 of the NIST PQC competition of Additional Signature Scehemes and described in
//
// https://csrc.nist.gov/csrc/media/Projects/pqc-dig-sig/documents/round-1/spec-files/mayo-spec-web.pdf
//
// This implemented the nibble-sliced version as proposed in
//
// https://eprint.iacr.org/2023/1683
package mode1
import (
"crypto"
"errors"
"io"
"github.com/cloudflare/circl/sign"
"github.com/cloudflare/circl/sign/mayo/mode1/internal"
)
const (
// Size of seed for NewKeyFromSeed
SeedSize = internal.KeySeedSize
// Size of a packed PublicKey
PublicKeySize = internal.PublicKeySize
// Size of a packed PrivateKey
PrivateKeySize = internal.PrivateKeySize
// Size of a signature
SignatureSize = internal.SignatureSize
)
// PublicKey is the type of Mayo1 public key
type PublicKey internal.PublicKey
// PrivateKey is the type of Mayo1 private key
type PrivateKey internal.PrivateKey
func (sk *PrivateKey) Scheme() sign.Scheme { return sch }
func (pk *PublicKey) Scheme() sign.Scheme { return sch }
// GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
pk, sk, err := internal.GenerateKey(rand)
return (*PublicKey)(pk), (*PrivateKey)(sk), err
}
// NewKeyFromSeed derives a public/private key pair using the given seed.
func NewKeyFromSeed(seed *[SeedSize]byte) (*PublicKey, *PrivateKey) {
pk, sk := internal.NewKeyFromSeed(seed)
return (*PublicKey)(pk), (*PrivateKey)(sk)
}
// Sign signs the given message using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
func Sign(sk *PrivateKey, msg []byte, rand io.Reader) ([]byte, error) {
return internal.Sign(
msg,
(*internal.PrivateKey)(sk),
rand,
)
}
// Verify checks whether the given signature by pk on msg is valid.
func Verify(pk *PublicKey, msg []byte, signature []byte) bool {
return internal.Verify(
(*internal.PublicKey)(pk),
msg,
signature,
)
}
// Sets pk to the public key encoded in buf.
func (pk *PublicKey) Unpack(buf *[PublicKeySize]byte) {
(*internal.PublicKey)(pk).Unpack(buf)
}
// Sets sk to the private key encoded in buf.
func (sk *PrivateKey) Unpack(buf *[PrivateKeySize]byte) {
(*internal.PrivateKey)(sk).Unpack(buf)
}
// Packs the public key into buf.
func (pk *PublicKey) Pack(buf *[PublicKeySize]byte) {
(*internal.PublicKey)(pk).Pack(buf)
}
// Packs the private key into buf.
func (sk *PrivateKey) Pack(buf *[PrivateKeySize]byte) {
(*internal.PrivateKey)(sk).Pack(buf)
}
// Packs the public key.
func (pk *PublicKey) Bytes() []byte {
var buf [PublicKeySize]byte
pk.Pack(&buf)
return buf[:]
}
// Packs the private key.
func (sk *PrivateKey) Bytes() []byte {
var buf [PrivateKeySize]byte
sk.Pack(&buf)
return buf[:]
}
// Packs the public key.
func (pk *PublicKey) MarshalBinary() ([]byte, error) {
return pk.Bytes(), nil
}
// Packs the private key.
func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
return sk.Bytes(), nil
}
// Unpacks the public key from data.
func (pk *PublicKey) UnmarshalBinary(data []byte) error {
if len(data) != PublicKeySize {
return errors.New("packed public key must be of mode1.PublicKeySize bytes")
}
var buf [PublicKeySize]byte
copy(buf[:], data)
pk.Unpack(&buf)
return nil
}
// Unpacks the private key from data.
func (sk *PrivateKey) UnmarshalBinary(data []byte) error {
if len(data) != PrivateKeySize {
return errors.New("packed private key must be of mode1.PrivateKeySize bytes")
}
var buf [PrivateKeySize]byte
copy(buf[:], data)
sk.Unpack(&buf)
return nil
}
// Sign signs the given message.
//
// opts.HashFunc() must return zero, which can be achieved by passing
// crypto.Hash(0) for opts. Will only return an error
// if opts.HashFunc() is non-zero.
//
// This function is used to make PrivateKey implement the crypto.Signer
// interface. The package-level Sign function might be more convenient
// to use.
func (sk *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (
signature []byte, err error) {
if opts.HashFunc() != crypto.Hash(0) {
return nil, errors.New("mayo: cannot sign hashed message")
}
return Sign(sk, msg, rand)
}
// Computes the public key corresponding to this private key.
//
// Returns a *PublicKey. The type crypto.PublicKey is used to make
// PrivateKey implement the crypto.Signer interface.
func (sk *PrivateKey) Public() crypto.PublicKey {
return (*internal.PrivateKey)(sk).Public
}
// Equal returns whether the two private keys equal.
func (sk *PrivateKey) Equal(other crypto.PrivateKey) bool {
castOther, ok := other.(*PrivateKey)
if !ok {
return false
}
return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(castOther))
}
// Equal returns whether the two public keys equal.
func (pk *PublicKey) Equal(other crypto.PublicKey) bool {
castOther, ok := other.(*PublicKey)
if !ok {
return false
}
return (*internal.PublicKey)(pk).Equal((*internal.PublicKey)(castOther))
}