github.com/cloudflare/circl@v1.5.0/sign/mldsa/mldsa87/dilithium.go (about) 1 // Code generated from pkg.templ.go. DO NOT EDIT. 2 3 // mldsa87 implements NIST signature scheme ML-DSA-87 as defined in FIPS204. 4 package mldsa87 5 6 import ( 7 "crypto" 8 cryptoRand "crypto/rand" 9 "errors" 10 "io" 11 12 "github.com/cloudflare/circl/sign" 13 common "github.com/cloudflare/circl/sign/internal/dilithium" 14 "github.com/cloudflare/circl/sign/mldsa/mldsa87/internal" 15 ) 16 17 const ( 18 // Size of seed for NewKeyFromSeed 19 SeedSize = common.SeedSize 20 21 // Size of a packed PublicKey 22 PublicKeySize = internal.PublicKeySize 23 24 // Size of a packed PrivateKey 25 PrivateKeySize = internal.PrivateKeySize 26 27 // Size of a signature 28 SignatureSize = internal.SignatureSize 29 ) 30 31 // PublicKey is the type of ML-DSA-87 public key 32 type PublicKey internal.PublicKey 33 34 // PrivateKey is the type of ML-DSA-87 private key 35 type PrivateKey internal.PrivateKey 36 37 // GenerateKey generates a public/private key pair using entropy from rand. 38 // If rand is nil, crypto/rand.Reader will be used. 39 func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) { 40 pk, sk, err := internal.GenerateKey(rand) 41 return (*PublicKey)(pk), (*PrivateKey)(sk), err 42 } 43 44 // NewKeyFromSeed derives a public/private key pair using the given seed. 45 func NewKeyFromSeed(seed *[SeedSize]byte) (*PublicKey, *PrivateKey) { 46 pk, sk := internal.NewKeyFromSeed(seed) 47 return (*PublicKey)(pk), (*PrivateKey)(sk) 48 } 49 50 // SignTo signs the given message and writes the signature into signature. 51 // It will panic if signature is not of length at least SignatureSize. 52 // 53 // ctx is the optional context string. Errors if ctx is larger than 255 bytes. 54 // A nil context string is equivalent to an empty context string. 55 func SignTo(sk *PrivateKey, msg, ctx []byte, randomized bool, sig []byte) error { 56 var rnd [32]byte 57 if randomized { 58 _, err := cryptoRand.Read(rnd[:]) 59 if err != nil { 60 return err 61 } 62 } 63 64 if len(ctx) > 255 { 65 return sign.ErrContextTooLong 66 } 67 68 internal.SignTo( 69 (*internal.PrivateKey)(sk), 70 func(w io.Writer) { 71 _, _ = w.Write([]byte{0}) 72 _, _ = w.Write([]byte{byte(len(ctx))}) 73 74 if ctx != nil { 75 _, _ = w.Write(ctx) 76 } 77 w.Write(msg) 78 }, 79 rnd, 80 sig, 81 ) 82 return nil 83 } 84 85 // Do not use. Implements ML-DSA.Sign_internal used for compatibility tests. 86 func (sk *PrivateKey) unsafeSignInternal(msg []byte, rnd [32]byte) []byte { 87 var ret [SignatureSize]byte 88 internal.SignTo( 89 (*internal.PrivateKey)(sk), 90 func(w io.Writer) { 91 _, _ = w.Write(msg) 92 }, 93 rnd, 94 ret[:], 95 ) 96 return ret[:] 97 } 98 99 // Do not use. Implements ML-DSA.Verify_internal used for compatibility tests. 100 func unsafeVerifyInternal(pk *PublicKey, msg, sig []byte) bool { 101 return internal.Verify( 102 (*internal.PublicKey)(pk), 103 func(w io.Writer) { 104 _, _ = w.Write(msg) 105 }, 106 sig, 107 ) 108 } 109 110 // Verify checks whether the given signature by pk on msg is valid. 111 // 112 // ctx is the optional context string. Fails if ctx is larger than 255 bytes. 113 // A nil context string is equivalent to an empty context string. 114 func Verify(pk *PublicKey, msg, ctx, sig []byte) bool { 115 if len(ctx) > 255 { 116 return false 117 } 118 return internal.Verify( 119 (*internal.PublicKey)(pk), 120 func(w io.Writer) { 121 _, _ = w.Write([]byte{0}) 122 _, _ = w.Write([]byte{byte(len(ctx))}) 123 124 if ctx != nil { 125 _, _ = w.Write(ctx) 126 } 127 _, _ = w.Write(msg) 128 }, 129 sig, 130 ) 131 } 132 133 // Sets pk to the public key encoded in buf. 134 func (pk *PublicKey) Unpack(buf *[PublicKeySize]byte) { 135 (*internal.PublicKey)(pk).Unpack(buf) 136 } 137 138 // Sets sk to the private key encoded in buf. 139 func (sk *PrivateKey) Unpack(buf *[PrivateKeySize]byte) { 140 (*internal.PrivateKey)(sk).Unpack(buf) 141 } 142 143 // Packs the public key into buf. 144 func (pk *PublicKey) Pack(buf *[PublicKeySize]byte) { 145 (*internal.PublicKey)(pk).Pack(buf) 146 } 147 148 // Packs the private key into buf. 149 func (sk *PrivateKey) Pack(buf *[PrivateKeySize]byte) { 150 (*internal.PrivateKey)(sk).Pack(buf) 151 } 152 153 // Packs the public key. 154 func (pk *PublicKey) Bytes() []byte { 155 var buf [PublicKeySize]byte 156 pk.Pack(&buf) 157 return buf[:] 158 } 159 160 // Packs the private key. 161 func (sk *PrivateKey) Bytes() []byte { 162 var buf [PrivateKeySize]byte 163 sk.Pack(&buf) 164 return buf[:] 165 } 166 167 // Packs the public key. 168 func (pk *PublicKey) MarshalBinary() ([]byte, error) { 169 return pk.Bytes(), nil 170 } 171 172 // Packs the private key. 173 func (sk *PrivateKey) MarshalBinary() ([]byte, error) { 174 return sk.Bytes(), nil 175 } 176 177 // Unpacks the public key from data. 178 func (pk *PublicKey) UnmarshalBinary(data []byte) error { 179 if len(data) != PublicKeySize { 180 return errors.New("packed public key must be of mldsa87.PublicKeySize bytes") 181 } 182 var buf [PublicKeySize]byte 183 copy(buf[:], data) 184 pk.Unpack(&buf) 185 return nil 186 } 187 188 // Unpacks the private key from data. 189 func (sk *PrivateKey) UnmarshalBinary(data []byte) error { 190 if len(data) != PrivateKeySize { 191 return errors.New("packed private key must be of mldsa87.PrivateKeySize bytes") 192 } 193 var buf [PrivateKeySize]byte 194 copy(buf[:], data) 195 sk.Unpack(&buf) 196 return nil 197 } 198 199 // Sign signs the given message. 200 // 201 // opts.HashFunc() must return zero, which can be achieved by passing 202 // crypto.Hash(0) for opts. rand is ignored. Will only return an error 203 // if opts.HashFunc() is non-zero. 204 // 205 // This function is used to make PrivateKey implement the crypto.Signer 206 // interface. The package-level SignTo function might be more convenient 207 // to use. 208 func (sk *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ( 209 sig []byte, err error) { 210 var ret [SignatureSize]byte 211 212 if opts.HashFunc() != crypto.Hash(0) { 213 return nil, errors.New("dilithium: cannot sign hashed message") 214 } 215 if err = SignTo(sk, msg, nil, false, ret[:]); err != nil { 216 return nil, err 217 } 218 219 return ret[:], nil 220 } 221 222 // Computes the public key corresponding to this private key. 223 // 224 // Returns a *PublicKey. The type crypto.PublicKey is used to make 225 // PrivateKey implement the crypto.Signer interface. 226 func (sk *PrivateKey) Public() crypto.PublicKey { 227 return (*PublicKey)((*internal.PrivateKey)(sk).Public()) 228 } 229 230 // Equal returns whether the two private keys equal. 231 func (sk *PrivateKey) Equal(other crypto.PrivateKey) bool { 232 castOther, ok := other.(*PrivateKey) 233 if !ok { 234 return false 235 } 236 return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(castOther)) 237 } 238 239 // Equal returns whether the two public keys equal. 240 func (pk *PublicKey) Equal(other crypto.PublicKey) bool { 241 castOther, ok := other.(*PublicKey) 242 if !ok { 243 return false 244 } 245 return (*internal.PublicKey)(pk).Equal((*internal.PublicKey)(castOther)) 246 } 247 248 // Boilerplate for generic signatures API 249 250 type scheme struct{} 251 252 var sch sign.Scheme = &scheme{} 253 254 // Scheme returns a generic signature interface for ML-DSA-87. 255 func Scheme() sign.Scheme { return sch } 256 257 func (*scheme) Name() string { return "ML-DSA-87" } 258 func (*scheme) PublicKeySize() int { return PublicKeySize } 259 func (*scheme) PrivateKeySize() int { return PrivateKeySize } 260 func (*scheme) SignatureSize() int { return SignatureSize } 261 func (*scheme) SeedSize() int { return SeedSize } 262 263 // TODO TLSIdentifier() and OID() 264 265 func (*scheme) SupportsContext() bool { 266 return true 267 } 268 269 func (*scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) { 270 return GenerateKey(nil) 271 } 272 273 func (*scheme) Sign( 274 sk sign.PrivateKey, 275 msg []byte, 276 opts *sign.SignatureOpts, 277 ) []byte { 278 var ctx []byte 279 sig := make([]byte, SignatureSize) 280 281 priv, ok := sk.(*PrivateKey) 282 if !ok { 283 panic(sign.ErrTypeMismatch) 284 } 285 if opts != nil && opts.Context != "" { 286 ctx = []byte(opts.Context) 287 } 288 err := SignTo(priv, msg, ctx, false, sig) 289 if err != nil { 290 panic(err) 291 } 292 293 return sig 294 } 295 296 func (*scheme) Verify( 297 pk sign.PublicKey, 298 msg, sig []byte, 299 opts *sign.SignatureOpts, 300 ) bool { 301 var ctx []byte 302 pub, ok := pk.(*PublicKey) 303 if !ok { 304 panic(sign.ErrTypeMismatch) 305 } 306 if opts != nil && opts.Context != "" { 307 ctx = []byte(opts.Context) 308 } 309 return Verify(pub, msg, ctx, sig) 310 } 311 312 func (*scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) { 313 if len(seed) != SeedSize { 314 panic(sign.ErrSeedSize) 315 } 316 var seed2 [SeedSize]byte 317 copy(seed2[:], seed) 318 return NewKeyFromSeed(&seed2) 319 } 320 321 func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) { 322 if len(buf) != PublicKeySize { 323 return nil, sign.ErrPubKeySize 324 } 325 326 var ( 327 buf2 [PublicKeySize]byte 328 ret PublicKey 329 ) 330 331 copy(buf2[:], buf) 332 ret.Unpack(&buf2) 333 return &ret, nil 334 } 335 336 func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) { 337 if len(buf) != PrivateKeySize { 338 return nil, sign.ErrPrivKeySize 339 } 340 341 var ( 342 buf2 [PrivateKeySize]byte 343 ret PrivateKey 344 ) 345 346 copy(buf2[:], buf) 347 ret.Unpack(&buf2) 348 return &ret, nil 349 } 350 351 func (sk *PrivateKey) Scheme() sign.Scheme { 352 return sch 353 } 354 355 func (sk *PublicKey) Scheme() sign.Scheme { 356 return sch 357 }