Replaced legacy `*.orly` module imports with `next.orly.dev/pkg` paths across the codebase for consistency. Removed legacy `go.mod` files from sub-packages, consolidating dependency management. Added Dockerfiles and configurations for benchmarking environments.
141 lines
3.0 KiB
Go
141 lines
3.0 KiB
Go
//go:build cgo
|
|
|
|
package p256k
|
|
|
|
import "C"
|
|
import (
|
|
"lol.mleku.dev/chk"
|
|
"lol.mleku.dev/errorf"
|
|
"lol.mleku.dev/log"
|
|
"next.orly.dev/pkg/crypto/ec"
|
|
"next.orly.dev/pkg/crypto/ec/secp256k1"
|
|
"next.orly.dev/pkg/interfaces/signer"
|
|
)
|
|
|
|
func init() {
|
|
log.T.Ln("using bitcoin/secp256k1 signature library")
|
|
}
|
|
|
|
// Signer implements the signer.I interface.
|
|
//
|
|
// Either the Sec or Pub must be populated, the former is for generating
|
|
// signatures, the latter is for verifying them.
|
|
//
|
|
// When using this library only for verification, a constructor that converts
|
|
// from bytes to PubKey is needed prior to calling Verify.
|
|
type Signer struct {
|
|
// SecretKey is the secret key.
|
|
SecretKey *SecKey
|
|
// PublicKey is the public key.
|
|
PublicKey *PubKey
|
|
// BTCECSec is needed for ECDH as currently the CGO bindings don't include it
|
|
BTCECSec *btcec.SecretKey
|
|
skb, pkb []byte
|
|
}
|
|
|
|
var _ signer.I = &Signer{}
|
|
|
|
// Generate a new Signer key pair using the CGO bindings to libsecp256k1
|
|
func (s *Signer) Generate() (err error) {
|
|
var cs *Sec
|
|
var cx *XPublicKey
|
|
if s.skb, s.pkb, cs, cx, err = Generate(); chk.E(err) {
|
|
return
|
|
}
|
|
s.SecretKey = &cs.Key
|
|
s.PublicKey = cx.Key
|
|
s.BTCECSec, _ = btcec.PrivKeyFromBytes(s.skb)
|
|
return
|
|
}
|
|
|
|
func (s *Signer) InitSec(skb []byte) (err error) {
|
|
var cs *Sec
|
|
var cx *XPublicKey
|
|
// var cp *PublicKey
|
|
if s.pkb, cs, cx, err = FromSecretBytes(skb); chk.E(err) {
|
|
if err.Error() != "provided secret generates a public key with odd Y coordinate, fixed version returned" {
|
|
log.E.Ln(err)
|
|
return
|
|
}
|
|
}
|
|
s.skb = skb
|
|
s.SecretKey = &cs.Key
|
|
s.PublicKey = cx.Key
|
|
// s.ECPublicKey = cp.Key
|
|
// needed for ecdh
|
|
s.BTCECSec, _ = btcec.PrivKeyFromBytes(s.skb)
|
|
return
|
|
}
|
|
|
|
func (s *Signer) InitPub(pub []byte) (err error) {
|
|
var up *Pub
|
|
if up, err = PubFromBytes(pub); chk.E(err) {
|
|
return
|
|
}
|
|
s.PublicKey = &up.Key
|
|
s.pkb = up.PubB()
|
|
return
|
|
}
|
|
|
|
func (s *Signer) Sec() (b []byte) {
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
return s.skb
|
|
}
|
|
func (s *Signer) Pub() (b []byte) {
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
return s.pkb
|
|
}
|
|
|
|
// func (s *Signer) ECPub() (b []byte) { return s.pkb }
|
|
|
|
func (s *Signer) Sign(msg []byte) (sig []byte, err error) {
|
|
if s.SecretKey == nil {
|
|
err = errorf.E("p256k: I secret not initialized")
|
|
return
|
|
}
|
|
u := ToUchar(msg)
|
|
if sig, err = Sign(u, s.SecretKey); chk.E(err) {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Signer) Verify(msg, sig []byte) (valid bool, err error) {
|
|
if s.PublicKey == nil {
|
|
err = errorf.E("p256k: Pubkey not initialized")
|
|
return
|
|
}
|
|
var uMsg, uSig *Uchar
|
|
if uMsg, err = Msg(msg); chk.E(err) {
|
|
return
|
|
}
|
|
if uSig, err = Sig(sig); chk.E(err) {
|
|
return
|
|
}
|
|
valid = Verify(uMsg, uSig, s.PublicKey)
|
|
if !valid {
|
|
err = errorf.E("p256k: invalid signature")
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Signer) ECDH(pubkeyBytes []byte) (secret []byte, err error) {
|
|
var pub *secp256k1.PublicKey
|
|
if pub, err = secp256k1.ParsePubKey(
|
|
append(
|
|
[]byte{0x02},
|
|
pubkeyBytes...,
|
|
),
|
|
); chk.E(err) {
|
|
return
|
|
}
|
|
secret = btcec.GenerateSharedSecret(s.BTCECSec, pub)
|
|
return
|
|
}
|
|
|
|
func (s *Signer) Zero() { Zero(s.SecretKey) }
|